Merge branch 'Syncplay:master' into master

This commit is contained in:
Daniel Wróbel 2021-06-25 11:37:12 +02:00 committed by GitHub
commit 7cf5c0ebd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 660 additions and 537 deletions

View File

@ -124,7 +124,7 @@ jobs:
appimage: appimage:
name: Build AppImage name: Build AppImage
runs-on: ubuntu-latest runs-on: ubuntu-18.04
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2

View File

@ -4,4 +4,5 @@ include syncplay/resources/*.png
include syncplay/resources/*.mng include syncplay/resources/*.mng
include syncplay/resources/*.lua include syncplay/resources/*.lua
include syncplay/resources/*.rtf include syncplay/resources/*.rtf
include syncplay/resources/*.txt
include syncplay/resources/lua/intf/*.lua include syncplay/resources/lua/intf/*.lua

View File

@ -23,7 +23,6 @@
# Syncplay # Syncplay
![GitHub Actions build status](https://github.com/Syncplay/syncplay/workflows/Build/badge.svg) ![GitHub Actions build status](https://github.com/Syncplay/syncplay/workflows/Build/badge.svg)
[![Appveyor build status](https://ci.appveyor.com/api/projects/status/github/Syncplay/syncplay)](https://ci.appveyor.com/project/Et0h/syncplay/branch/master)
Solution to synchronize video playback across multiple instances of mpv, VLC, MPC-HC, MPC-BE and mplayer2 over the Internet. Solution to synchronize video playback across multiple instances of mpv, VLC, MPC-HC, MPC-BE and mplayer2 over the Internet.
@ -45,7 +44,7 @@ Syncplay is not a file sharing service.
## License ## License
This project, the Syncplay released binaries, and all the files included in this repository unless stated otherwise in the header of the file, are licensed under the [Apache License, version 2.0](https://www.apache.org/licenses/LICENSE-2.0.html). A copy of this license is included in the LICENSE file of this repository. Licenses and attribution notices for third-party media are set out in [third-party-notices.rtf](syncplay/resources/third-party-notices.rtf). This project, the Syncplay released binaries, and all the files included in this repository unless stated otherwise in the header of the file, are licensed under the [Apache License, version 2.0](https://www.apache.org/licenses/LICENSE-2.0.html). A copy of this license is included in the LICENSE file of this repository. Licenses and attribution notices for third-party media are set out in [third-party-notices.txt](syncplay/resources/third-party-notices.txt).
## Authors ## Authors
* *Initial concept and core internals developer* - Uriziel. * *Initial concept and core internals developer* - Uriziel.

View File

@ -11,7 +11,7 @@ import syncplay
APP = ['syncplayClient.py'] APP = ['syncplayClient.py']
DATA_FILES = [ DATA_FILES = [
('resources', glob('syncplay/resources/*.png') + glob('syncplay/resources/*.rtf') + glob('syncplay/resources/*.lua')), ('resources', glob('syncplay/resources/*.png') + glob('syncplay/resources/*.rtf') + glob('syncplay/resources/*.txt') + glob('syncplay/resources/*.lua')),
('resources/lua/intf', glob('syncplay/resources/lua/intf/*.lua')) ('resources/lua/intf', glob('syncplay/resources/lua/intf/*.lua'))
] ]
OPTIONS = { OPTIONS = {

View File

@ -726,7 +726,7 @@ guiIcons = glob('syncplay/resources/*.ico') + glob('syncplay/resources/*.png') +
resources = [ resources = [
"syncplay/resources/syncplayintf.lua", "syncplay/resources/syncplayintf.lua",
"syncplay/resources/license.rtf", "syncplay/resources/license.rtf",
"syncplay/resources/third-party-notices.rtf" "syncplay/resources/third-party-notices.txt"
] ]
resources.extend(guiIcons) resources.extend(guiIcons)
intf_resources = ["syncplay/resources/lua/intf/syncplay.lua"] intf_resources = ["syncplay/resources/lua/intf/syncplay.lua"]

View File

@ -1,5 +1,5 @@
version = '1.6.8' version = '1.6.8'
revision = ' development' revision = ''
milestone = 'Yoitsu' milestone = 'Yoitsu'
release_number = '96' release_number = '98'
projectURL = 'https://syncplay.pl/' projectURL = 'https://syncplay.pl/'

View File

@ -500,6 +500,11 @@ class SyncplayClient(object):
return True return True
return self._globalPaused return self._globalPaused
def eofReportedByPlayer(self):
if self.playlist.notJustChangedPlaylist() and self.userlist.currentUser.file:
self.ui.showDebugMessage("Fixing file duration to allow for playlist advancement")
self.userlist.currentUser.file["duration"] = self._playerPosition
def updateFile(self, filename, duration, path): def updateFile(self, filename, duration, path):
self.lastUpdatedFileTime = time.time() self.lastUpdatedFileTime = time.time()
newPath = "" newPath = ""

View File

@ -29,7 +29,7 @@ MPLAYER_OSD_LEVEL = 1
UI_TIME_FORMAT = "[%X] " UI_TIME_FORMAT = "[%X] "
CONFIG_NAMES = [".syncplay", "syncplay.ini"] # Syncplay searches first to last CONFIG_NAMES = [".syncplay", "syncplay.ini"] # Syncplay searches first to last
DEFAULT_CONFIG_NAME = "syncplay.ini" DEFAULT_CONFIG_NAME = "syncplay.ini"
RECENT_CLIENT_THRESHOLD = "1.6.7" # This and higher considered 'recent' clients (no warnings) RECENT_CLIENT_THRESHOLD = "1.6.8" # This and higher considered 'recent' clients (no warnings)
MUSIC_FORMATS = [".mp3", ".m4a", ".m4p", ".wav", ".aiff", ".r", ".ogg", ".flac"] # ALL LOWER CASE! MUSIC_FORMATS = [".mp3", ".m4a", ".m4p", ".wav", ".aiff", ".r", ".ogg", ".flac"] # ALL LOWER CASE!
WARN_OLD_CLIENTS = True # Use MOTD to inform old clients to upgrade WARN_OLD_CLIENTS = True # Use MOTD to inform old clients to upgrade
LIST_RELATIVE_CONFIGS = True # Print list of relative configs loaded LIST_RELATIVE_CONFIGS = True # Print list of relative configs loaded
@ -131,7 +131,7 @@ COMMANDS_DELETE = ['delete', 'd', 'qd']
MPC_MIN_VER = "1.6.4" MPC_MIN_VER = "1.6.4"
MPC_BE_MIN_VER = "1.5.2.3123" MPC_BE_MIN_VER = "1.5.2.3123"
VLC_MIN_VERSION = "2.2.1" VLC_MIN_VERSION = "2.2.1"
VLC_INTERFACE_VERSION = "0.3.6" VLC_INTERFACE_VERSION = "0.3.7"
VLC_LATENCY_ERROR_THRESHOLD = 2.0 VLC_LATENCY_ERROR_THRESHOLD = 2.0
MPV_UNRESPONSIVE_THRESHOLD = 60.0 MPV_UNRESPONSIVE_THRESHOLD = 60.0
CONTROLLED_ROOMS_MIN_VERSION = "1.3.0" CONTROLLED_ROOMS_MIN_VERSION = "1.3.0"
@ -289,7 +289,7 @@ VLC_SLAVE_EXTRA_ARGS = getValueForOS({
MPV_SUPERSEDE_IF_DUPLICATE_COMMANDS = ["set_property time-pos ", "loadfile "] MPV_SUPERSEDE_IF_DUPLICATE_COMMANDS = ["set_property time-pos ", "loadfile "]
MPV_REMOVE_BOTH_IF_DUPLICATE_COMMANDS = ["cycle pause"] MPV_REMOVE_BOTH_IF_DUPLICATE_COMMANDS = ["cycle pause"]
MPLAYER_ANSWER_REGEX = "^ANS_([a-zA-Z_-]+)=(.+)$|^(Exiting)\.\.\. \((.+)\)$" MPLAYER_ANSWER_REGEX = "^ANS_([a-zA-Z_-]+)=(.+)$|^(Exiting)\.\.\. \((.+)\)$"
VLC_ANSWER_REGEX = r"(?:^(?P<command>[a-zA-Z_]+)(?:\: )?(?P<argument>.*))" VLC_ANSWER_REGEX = r"(?:^(?P<command>[a-zA-Z_-]+)(?:\: )?(?P<argument>.*))"
UI_COMMAND_REGEX = r"^(?P<command>[^\ ]+)(?:\ (?P<parameter>.+))?" UI_COMMAND_REGEX = r"^(?P<command>[^\ ]+)(?:\ (?P<parameter>.+))?"
UI_OFFSET_REGEX = r"^(?:o|offset)\ ?(?P<sign>[/+-])?(?P<time>\d{1,9}(?:[^\d\.](?:\d{1,9})){0,2}(?:\.(?:\d{1,3}))?)$" UI_OFFSET_REGEX = r"^(?:o|offset)\ ?(?P<sign>[/+-])?(?P<time>\d{1,9}(?:[^\d\.](?:\d{1,9})){0,2}(?:\.(?:\d{1,3}))?)$"
UI_SEEK_REGEX = r"^(?:s|seek)?\ ?(?P<sign>[+-])?(?P<time>\d{1,4}(?:[^\d\.](?:\d{1,6})){0,2}(?:\.(?:\d{1,3}))?)$" UI_SEEK_REGEX = r"^(?:s|seek)?\ ?(?P<sign>[+-])?(?P<time>\d{1,4}(?:[^\d\.](?:\d{1,6})){0,2}(?:\.(?:\d{1,3}))?)$"

View File

@ -47,7 +47,8 @@ pt_BR = {
"identifying-as-controller-notification": "Identificando-se como operador da sala com a senha '{}'...", "identifying-as-controller-notification": "Identificando-se como operador da sala com a senha '{}'...",
"failed-to-identify-as-controller-notification": "{} falhou ao se identificar como operador da sala.", "failed-to-identify-as-controller-notification": "{} falhou ao se identificar como operador da sala.",
"authenticated-as-controller-notification": "{} autenticou-se como um operador da sala", "authenticated-as-controller-notification": "{} autenticou-se como um operador da sala",
"created-controlled-room-notification": "Criou a sala gerenciada '{}' com a senha '{}'. Por favor, salve essa informação para futura referência!\n\nIn managed rooms everyone is kept in sync with the room operator(s) who are the only ones who can pause, unpause, seek, and change the playlist.\n\nYou should ask regular viewers to join the room '{}' but the room operators can join the room '{}' to automatically authenticate themselves.", # RoomName, operatorPassword, roomName, roomName:operatorPassword # TODO: Translate "created-controlled-room-notification": "Criou a sala gerenciada '{}' com a senha '{}'. Por favor, salve essa informação para futura referência!\n\nEm uma sala gerenciada, todos são mantidos em sincronia com o(s) operador(es) de sala, que é/são o(s) único(s) que pode(m) pausar, despausar, pular, e mudar a playlist.\n\nVocê deve pedir usuários comuns para se entrarem à sala '{}', mas os operadores de sala podem se entrar à sala '{}' para autenticarem-se automaticamente.", # RoomName, operatorPassword, roomName, roomName:operatorPassword
"file-different-notification": "O arquivo que você está tocando parece ser diferente do arquivo de {}", # User "file-different-notification": "O arquivo que você está tocando parece ser diferente do arquivo de {}", # User
"file-differences-notification": "Seus arquivos se diferem da(s) seguinte(s) forma(s): {}", # Differences "file-differences-notification": "Seus arquivos se diferem da(s) seguinte(s) forma(s): {}", # Differences
@ -87,10 +88,10 @@ pt_BR = {
"commandlist-notification/create": "\tc [nome] - cria sala gerenciado usando o nome da sala atual", "commandlist-notification/create": "\tc [nome] - cria sala gerenciado usando o nome da sala atual",
"commandlist-notification/auth": "\ta [senha] - autentica-se como operador da sala com a senha", "commandlist-notification/auth": "\ta [senha] - autentica-se como operador da sala com a senha",
"commandlist-notification/chat": "\tch [mensagem] - envia uma mensagem no chat da sala", "commandlist-notification/chat": "\tch [mensagem] - envia uma mensagem no chat da sala",
"commandList-notification/queue": "\tqa [file/url] - add file or url to bottom of playlist", # TO DO: Translate "commandList-notification/queue": "\tqa [file/url] - adiciona arquivo ou URL para o final da playlist",
"commandList-notification/playlist": "\tql - show the current playlist", # TO DO: Translate "commandList-notification/playlist": "\tql - mostra a playlist atual",
"commandList-notification/select": "\tqs [index] - select given entry in the playlist", # TO DO: Translate "commandList-notification/select": "\tqs [index] - seleciona uma dada entrada na playlist",
"commandList-notification/delete": "\tqd [index] - delete the given entry from the playlist", # TO DO: Translate "commandList-notification/delete": "\tqd [index] - deleta uma dada entrada na playlist",
"syncplay-version-notification": "Versão do Syncplay: {}", # syncplay.version "syncplay-version-notification": "Versão do Syncplay: {}", # syncplay.version
"more-info-notification": "Mais informações disponíveis em: {}", # projectURL "more-info-notification": "Mais informações disponíveis em: {}", # projectURL
@ -110,8 +111,8 @@ pt_BR = {
"mpc-slave-error": "Não foi possível abrir o MPC no slave mode!", "mpc-slave-error": "Não foi possível abrir o MPC no slave mode!",
"mpc-version-insufficient-error": "A versão do MPC é muito antiga, por favor use `mpc-hc` >= `{}`", "mpc-version-insufficient-error": "A versão do MPC é muito antiga, por favor use `mpc-hc` >= `{}`",
"mpc-be-version-insufficient-error": "A versão do MPC-BE é muito antiga, por favor use `mpc-be` >= `{}`", "mpc-be-version-insufficient-error": "A versão do MPC-BE é muito antiga, por favor use `mpc-be` >= `{}`",
"mpv-version-error": "O motivo pelo qual o mpv não pode ser iniciado pode ser devido ao uso de argumentos da linha de comando não suportados ou a uma versão não suportada do mpv.", "mpv-version-error": "O Syncplay não é compatível com esta versão do mpv. Por favor, use uma versão diferente do mpv (por exemplo, Git HEAD).",
"mpv-failed-advice": "The reason mpv cannot start may be due to the use of unsupported command line arguments or an unsupported version of mpv.", # TODO: Translate "mpv-failed-advice": "O motivo pelo qual o mpv não pode ser iniciado pode ser devido ao uso de argumentos da linha de comando não suportados ou a uma versão não suportada do mpv.",
"player-file-open-error": "O reprodutor falhou ao abrir o arquivo", "player-file-open-error": "O reprodutor falhou ao abrir o arquivo",
"player-path-error": "O caminho até o arquivo executável do reprodutor não está configurado corretamente. Os reprodutores suportados são: mpv, mpv.net, VLC, MPC-HC, MPC-BE, mplayer2 e IINA", "player-path-error": "O caminho até o arquivo executável do reprodutor não está configurado corretamente. Os reprodutores suportados são: mpv, mpv.net, VLC, MPC-HC, MPC-BE, mplayer2 e IINA",
"hostname-empty-error": "O endereço do servidor não pode ser vazio", "hostname-empty-error": "O endereço do servidor não pode ser vazio",
@ -133,10 +134,10 @@ pt_BR = {
"not-json-error": "Não é uma string codificada como JSON\n", "not-json-error": "Não é uma string codificada como JSON\n",
"hello-arguments-error": "Not enough Hello arguments\n", # DO NOT TRANSLATE "hello-arguments-error": "Not enough Hello arguments\n", # DO NOT TRANSLATE
"version-mismatch-error": "Discrepância entre versões do client e do servidor\n", "version-mismatch-error": "Discrepância entre versões do client e do servidor\n",
"vlc-failed-connection": "Falha ao conectar ao VLC. Se você não instalou o syncplay.lua e está usando a versão mais recente do VLC, por favor veja https://syncplay.pl/LUA/ para mais instruções.Syncplay and VLC 4 are not currently compatible, so either use VLC 3 or an alternative such as mpv.", # TO DO: TRANSLATE "vlc-failed-connection": "Falha ao conectar ao VLC. Se você não instalou o syncplay.lua e está usando a versão mais recente do VLC, por favor veja https://syncplay.pl/LUA/ para mais instruções. Syncplay e VLC 4 são atualmente incompatíveis, portanto ou use VLC 3 ou use outro reprodutor, como o mpv.",
"vlc-failed-noscript": "O VLC reportou que a interface de script do syncplay.lua não foi instalada. Por favor, veja https://syncplay.pl/LUA/ para mais instruções.", "vlc-failed-noscript": "O VLC reportou que a interface de script do syncplay.lua não foi instalada. Por favor, veja https://syncplay.pl/LUA/ para mais instruções.",
"vlc-failed-versioncheck": "Esta versão do VLC não é suportada pelo Syncplay.", "vlc-failed-versioncheck": "Esta versão do VLC não é suportada pelo Syncplay.",
"vlc-initial-warning": 'VLC does not always provide accurate position information to Syncplay, especially for .mp4 and .avi files. If you experience problems with erroneous seeking then please try an alternative media player such as <a href="https://mpv.io/">mpv</a> (or <a href="https://github.com/stax76/mpv.net/">mpv.net</a> for Windows users).', # TODO: Translate "vlc-initial-warning": 'O VLC nem sempre fornece informações precisas de posição para o Syncplay, especialmente para arquivos .mp4 ou .avi. Se você experienciar problemas com busca (seeking) incorreta, por favor, tente um reprodutor de mídia alternativo, como o <a href="https://mpv.io/">mpv</a> (ou <a href="https://github.com/stax76/mpv.net/">mpv.net</a>, uma alternativa mais simples do mpv a usuários Windows).',
"feature-sharedPlaylists": "playlists compartilhadas", # used for not-supported-by-server-error "feature-sharedPlaylists": "playlists compartilhadas", # used for not-supported-by-server-error
"feature-chat": "chat", # used for not-supported-by-server-error "feature-chat": "chat", # used for not-supported-by-server-error
@ -189,7 +190,7 @@ pt_BR = {
"name-label": "Nome de usuário (opcional): ", "name-label": "Nome de usuário (opcional): ",
"password-label": "Senha do servidor (se existir): ", "password-label": "Senha do servidor (se existir): ",
"room-label": "Sala padrão: ", "room-label": "Sala padrão: ",
"roomlist-msgbox-label": "Edit room list (one per line)", # TODO: Translate "roomlist-msgbox-label": "Edite a lista de salas (uma por linha)",
"media-setting-title": "Configurações do reprodutor de mídia", "media-setting-title": "Configurações do reprodutor de mídia",
"executable-path-label": "Executável do reprodutor:", "executable-path-label": "Executável do reprodutor:",
@ -207,7 +208,7 @@ pt_BR = {
"filename-privacy-label": "Informação do nome do arquivo:", "filename-privacy-label": "Informação do nome do arquivo:",
"filesize-privacy-label": "Informação do tamanho do arquivo:", "filesize-privacy-label": "Informação do tamanho do arquivo:",
"checkforupdatesautomatically-label": "Verificar atualizações do Syncplay automaticamente", "checkforupdatesautomatically-label": "Verificar atualizações do Syncplay automaticamente",
"autosavejoinstolist-label": "Add rooms you join to the room list", # TO DO: Translate "autosavejoinstolist-label": "Adicionar salas que você entra para a lista de salas",
"slowondesync-label": "Diminuir velocidade em dessincronizações menores (não suportado pelo MPC-HC/BE)", "slowondesync-label": "Diminuir velocidade em dessincronizações menores (não suportado pelo MPC-HC/BE)",
"rewindondesync-label": "Retroceder em dessincronização maiores (recomendado)", "rewindondesync-label": "Retroceder em dessincronização maiores (recomendado)",
"fastforwardondesync-label": "Avançar se estiver ficando para trás (recomendado)", "fastforwardondesync-label": "Avançar se estiver ficando para trás (recomendado)",
@ -216,7 +217,7 @@ pt_BR = {
"pauseonleave-label": "Pausar quando um usuário sair (por exemplo, se for desconectado)", "pauseonleave-label": "Pausar quando um usuário sair (por exemplo, se for desconectado)",
"readiness-title": "Estado de prontidão inicial", "readiness-title": "Estado de prontidão inicial",
"readyatstart-label": "Marque-me como 'pronto para assistir' por padrão", "readyatstart-label": "Marque-me como 'pronto para assistir' por padrão",
"forceguiprompt-label": "Não mostrar sempre a janela de configuração do Syncplay", # (Inverted) "forceguiprompt-label": "Não mostrar a janela de configuração do Syncplay", # (Inverted)
"showosd-label": "Ativar mensagens na tela (OSD)", "showosd-label": "Ativar mensagens na tela (OSD)",
"showosdwarnings-label": "Incluir avisos (por exemplo, quando arquivos são diferentes, usuários não estão prontos, etc)", "showosdwarnings-label": "Incluir avisos (por exemplo, quando arquivos são diferentes, usuários não estão prontos, etc)",
@ -231,7 +232,7 @@ pt_BR = {
"readiness-label": "Play/Pause", "readiness-label": "Play/Pause",
"misc-label": "Miscelânea", "misc-label": "Miscelânea",
"core-behaviour-title": "Comportamento da sala padrão", "core-behaviour-title": "Comportamento da sala padrão",
"syncplay-internals-title": "Syncplay internals", "syncplay-internals-title": "Configurações internas do Syncplay",
"syncplay-mediasearchdirectories-title": "Diretórios a buscar por mídias", "syncplay-mediasearchdirectories-title": "Diretórios a buscar por mídias",
"syncplay-mediasearchdirectories-label": "Diretórios a buscar por mídias (um caminho por linha)", "syncplay-mediasearchdirectories-label": "Diretórios a buscar por mídias (um caminho por linha)",
"sync-label": "Sincronizar", "sync-label": "Sincronizar",
@ -333,7 +334,7 @@ pt_BR = {
"startTLS-initiated": "Tentando estabelecer conexão segura", "startTLS-initiated": "Tentando estabelecer conexão segura",
"startTLS-secure-connection-ok": "Conexão segura estabelecida ({})", "startTLS-secure-connection-ok": "Conexão segura estabelecida ({})",
"startTLS-server-certificate-invalid": 'Não foi possível estabelecer uma conexão segura. O servidor usa um certificado de segurança inválido. Essa comunicação pode ser interceptada por terceiros. Para mais detalhes de solução de problemas, consulte <a href="https://syncplay.pl/trouble">aqui</a>.', "startTLS-server-certificate-invalid": 'Não foi possível estabelecer uma conexão segura. O servidor usa um certificado de segurança inválido. Essa comunicação pode ser interceptada por terceiros. Para mais detalhes de solução de problemas, consulte <a href="https://syncplay.pl/trouble">aqui</a>.',
"startTLS-server-certificate-invalid-DNS-ID": "Syncplay does not trust this server because it uses a certificate that is not valid for its hostname.", # TODO: Translate "startTLS-server-certificate-invalid-DNS-ID": "O Syncplay não confia neste servidor pois ele usa um certificado que não é válido para seu hostname.",
"startTLS-not-supported-client": "Este client não possui suporte para TLS", "startTLS-not-supported-client": "Este client não possui suporte para TLS",
"startTLS-not-supported-server": "Este servidor não possui suporte para TLS", "startTLS-not-supported-server": "Este servidor não possui suporte para TLS",
@ -381,7 +382,7 @@ pt_BR = {
"password-tooltip": "Senhas são necessárias apenas para servidores privados.", "password-tooltip": "Senhas são necessárias apenas para servidores privados.",
"room-tooltip": "O nome da sala para se conectar pode ser praticamente qualquer coisa, mas você só irá se sincronizar com pessoas na mesma sala.", "room-tooltip": "O nome da sala para se conectar pode ser praticamente qualquer coisa, mas você só irá se sincronizar com pessoas na mesma sala.",
"edit-rooms-tooltip": "Edit room list.", # TO DO: Translate "edit-rooms-tooltip": "Edite a lista de salas.",
"executable-path-tooltip": "Localização do seu reprodutor de mídia preferido (mpv, mpv.net, VLC, MPC-HC/BE, mplayer2 ou IINA).", "executable-path-tooltip": "Localização do seu reprodutor de mídia preferido (mpv, mpv.net, VLC, MPC-HC/BE, mplayer2 ou IINA).",
"media-path-tooltip": "Localização do vídeo ou transmissão a ser aberto. Necessário com o mplayer2.", "media-path-tooltip": "Localização do vídeo ou transmissão a ser aberto. Necessário com o mplayer2.",
@ -395,12 +396,12 @@ pt_BR = {
"privacy-sendhashed-tooltip": "Mandar versão hasheada da informação, tornando-a menos visível aos outros clients.", "privacy-sendhashed-tooltip": "Mandar versão hasheada da informação, tornando-a menos visível aos outros clients.",
"privacy-dontsend-tooltip": "Não enviar esta informação ao servidor. Esta opção oferece a maior privacidade.", "privacy-dontsend-tooltip": "Não enviar esta informação ao servidor. Esta opção oferece a maior privacidade.",
"checkforupdatesautomatically-tooltip": "Checar o site do Syncplay regularmente para ver se alguma nova versão do Syncplay está disponível.", "checkforupdatesautomatically-tooltip": "Checar o site do Syncplay regularmente para ver se alguma nova versão do Syncplay está disponível.",
"autosavejoinstolist-tooltip": "When you join a room in a server, automatically remember the room name in the list of rooms to join.", # TO DO: Translate "autosavejoinstolist-tooltip": "Quando você se juntar a uma sala em um servidor, automaticamente lembrar do nome da sala na lista de salas para entrar.",
"slowondesync-tooltip": "Reduzir a velocidade de reprodução temporariamente quando necessário para trazer você de volta à sincronia com os outros espectadores. Não suportado pelo MPC-HC/BE.", "slowondesync-tooltip": "Reduzir a velocidade de reprodução temporariamente quando necessário para trazer você de volta à sincronia com os outros espectadores. Não suportado pelo MPC-HC/BE.",
"dontslowdownwithme-tooltip": "Significa que outros não serão desacelerados ou retrocedidos se sua reprodução estiver ficando para trás. Útil para operadores de salas.", "dontslowdownwithme-tooltip": "Significa que outros não serão desacelerados ou retrocedidos se sua reprodução estiver ficando para trás. Útil para operadores de salas.",
"pauseonleave-tooltip": "Pausar reprodução se você for disconectado ou se alguém sair da sua sala.", "pauseonleave-tooltip": "Pausar reprodução se você for desconectado ou se alguém sair da sua sala.",
"readyatstart-tooltip": "Definir-se como 'pronto' ao começar (do contrário você será definido como 'não pronto' até mudar seu estado de prontidão)", "readyatstart-tooltip": "Definir-se como 'pronto' ao começar (do contrário você será definido como 'não pronto' até mudar seu estado de prontidão)",
"forceguiprompt-tooltip": "Diálogo de configuração não é exibido ao abrir um arquivo com o Syncplay.", # (Inverted) "forceguiprompt-tooltip": "Diálogo de configuração não será exibido ao abrir um arquivo com o Syncplay.", # (Inverted)
"nostore-tooltip": "Começar Syncplay com a dada configuração, mas não guardar as mudanças permanentemente.", # (Inverted) "nostore-tooltip": "Começar Syncplay com a dada configuração, mas não guardar as mudanças permanentemente.", # (Inverted)
"rewindondesync-tooltip": "Retroceder automaticamente quando necessário para sincronizar. Desabilitar isto pode resultar em grandes dessincronizações!", "rewindondesync-tooltip": "Retroceder automaticamente quando necessário para sincronizar. Desabilitar isto pode resultar em grandes dessincronizações!",
"fastforwardondesync-tooltip": "Avançar automaticamente quando estiver fora de sincronia com o operador da sala (ou sua posição pretendida caso 'Nunca desacelerar ou retroceder outros' estiver habilitada).", "fastforwardondesync-tooltip": "Avançar automaticamente quando estiver fora de sincronia com o operador da sala (ou sua posição pretendida caso 'Nunca desacelerar ou retroceder outros' estiver habilitada).",
@ -516,6 +517,6 @@ pt_BR = {
"playlist-instruction-item-message": "Arraste um arquivo aqui para adicioná-lo à playlist compartilhada.", "playlist-instruction-item-message": "Arraste um arquivo aqui para adicioná-lo à playlist compartilhada.",
"sharedplaylistenabled-tooltip": "Operadores da sala podem adicionar arquivos para a playlist compartilhada para tornar mais fácil para todo mundo assistir a mesma coisa. Configure os diretórios de mídia em 'Miscelânea'.", "sharedplaylistenabled-tooltip": "Operadores da sala podem adicionar arquivos para a playlist compartilhada para tornar mais fácil para todo mundo assistir a mesma coisa. Configure os diretórios de mídia em 'Miscelânea'.",
"playlist-empty-error": "Playlist is currently empty.", # TO DO: Translate "playlist-empty-error": "A playlist está atualemnte vazia.",
"playlist-invalid-index-error": "Invalid playlist index", # TO DO: Translate "playlist-invalid-index-error": "Índice inválido na playlist.",
} }

View File

@ -213,6 +213,9 @@ class MpvPlayer(BasePlayer):
else: else:
return self._position return self._position
def eofDetected(self):
self._client.eofReportedByPlayer()
def _storePosition(self, value): def _storePosition(self, value):
if value is None: if value is None:
self._client.ui.showDebugMessage("NONE TYPE POSITION!") self._client.ui.showDebugMessage("NONE TYPE POSITION!")
@ -420,11 +423,13 @@ class MpvPlayer(BasePlayer):
def _handleUnknownLine(self, line): def _handleUnknownLine(self, line):
self.mpvErrorCheck(line) self.mpvErrorCheck(line)
if "<chat>" in line: if "<chat>" in line:
line = line.replace(constants.MPV_INPUT_BACKSLASH_SUBSTITUTE_CHARACTER, "\\") line = line.replace(constants.MPV_INPUT_BACKSLASH_SUBSTITUTE_CHARACTER, "\\")
self._listener.sendChat(line[6:-7]) self._listener.sendChat(line[6:-7])
if "<eof>" in line:
self.eofDetected()
if "<paused=" in line and ", pos=" in line: if "<paused=" in line and ", pos=" in line:
update_string = line.replace(">", "<").replace("=", "<").replace(", ", "<").split("<") update_string = line.replace(">", "<").replace("=", "<").replace(", ", "<").split("<")
paused_update = update_string[2] paused_update = update_string[2]

View File

@ -297,7 +297,7 @@ class VlcPlayer(BasePlayer):
# value = value.decode('utf-8') # value = value.decode('utf-8')
self._filepath = value self._filepath = value
self._pathAsk.set() self._pathAsk.set()
elif name == "duration": elif name == "duration" or name == "duration-change":
if value == "no-input": if value == "no-input":
self._duration = 0 self._duration = 0
elif value == "invalid-32-bit-value": elif value == "invalid-32-bit-value":
@ -306,6 +306,11 @@ class VlcPlayer(BasePlayer):
else: else:
self._duration = float(value.replace(",", ".")) self._duration = float(value.replace(",", "."))
self._durationAsk.set() self._durationAsk.set()
if name == "duration-change":
self._filechanged = True
t = threading.Thread(target=self._onFileUpdate)
t.setDaemon(True)
t.start()
elif name == "playstate": elif name == "playstate":
self._paused = bool(value != 'playing') if (value != "no-input" and self._filechanged == False) else self._client.getGlobalPaused() self._paused = bool(value != 'playing') if (value != "no-input" and self._filechanged == False) else self._client.getGlobalPaused()
diff = time.time() - self._lastVLCPositionUpdate if self._lastVLCPositionUpdate else 0 diff = time.time() - self._lastVLCPositionUpdate if self._lastVLCPositionUpdate else 0

View File

@ -5,7 +5,7 @@
Principal author: Etoh Principal author: Etoh
Other contributors: DerGenaue, jb, Pilotat Other contributors: DerGenaue, jb, Pilotat
Project: https://syncplay.pl/ Project: https://syncplay.pl/
Version: 0.3.6 Version: 0.3.7
Note: Note:
* This interface module is intended to be used in conjunction with Syncplay. * This interface module is intended to be used in conjunction with Syncplay.
@ -78,7 +78,7 @@ Syncplay should install this automatically to your user folder.
--]==========================================================================] --]==========================================================================]
local connectorversion = "0.3.6" local connectorversion = "0.3.7"
local vlcversion = vlc.misc.version() local vlcversion = vlc.misc.version()
local vlcmajorversion = tonumber(vlcversion:sub(1,1)) -- get the major version of VLC local vlcmajorversion = tonumber(vlcversion:sub(1,1)) -- get the major version of VLC
@ -114,6 +114,8 @@ local newfilepath
local newinputstate local newinputstate
local oldtitle = 0 local oldtitle = 0
local newtitle = 0 local newtitle = 0
local oldduration = 0
local newduration = 0
local channel1 local channel1
local channel2 local channel2
@ -179,6 +181,11 @@ function detectchanges()
oldtitle = newtitle oldtitle = newtitle
notificationbuffer = notificationbuffer .. "playstate"..msgseperator..tostring(get_play_state())..msgterminator notificationbuffer = notificationbuffer .. "playstate"..msgseperator..tostring(get_play_state())..msgterminator
notificationbuffer = notificationbuffer .. "position"..msgseperator..tostring(get_time())..msgterminator notificationbuffer = notificationbuffer .. "position"..msgseperator..tostring(get_time())..msgterminator
newduration = get_duration()
if oldduration ~= newduration then
oldduration = newduration
notificationbuffer = notificationbuffer .. "duration-change"..msgseperator..tostring(newduration)..msgterminator
end
else else
notificationbuffer = notificationbuffer .. "playstate"..msgseperator..noinput..msgterminator notificationbuffer = notificationbuffer .. "playstate"..msgseperator..noinput..msgterminator
notificationbuffer = notificationbuffer .. "position"..msgseperator..noinput..msgterminator notificationbuffer = notificationbuffer .. "position"..msgseperator..noinput..msgterminator
@ -189,7 +196,6 @@ function detectchanges()
oldinputstate = newinputstate oldinputstate = newinputstate
notificationbuffer = notificationbuffer.."inputstate-change"..msgseperator..tostring(newinputstate)..msgterminator notificationbuffer = notificationbuffer.."inputstate-change"..msgseperator..tostring(newinputstate)..msgterminator
end end
return notificationbuffer return notificationbuffer
end end
@ -406,7 +412,7 @@ function get_duration ()
local i = 0 local i = 0
response = 0 response = 0
repeat repeat
vlc.misc.mwait(vlc.misc.mdate() + durationdelay) -- vlc.misc.mwait(vlc.misc.mdate() + durationdelay)
if item and item:duration() then if item and item:duration() then
response = item:duration() response = item:duration()
if response < 1 then if response < 1 then
@ -420,7 +426,6 @@ function get_duration ()
else else
errormsg = noinput errormsg = noinput
end end
return response, errormsg return response, errormsg
end end
@ -490,7 +495,10 @@ function do_command ( command, argument)
if command == "get-interface-version" then response = "interface-version"..msgseperator..connectorversion..msgterminator if command == "get-interface-version" then response = "interface-version"..msgseperator..connectorversion..msgterminator
elseif command == "get-vlc-version" then response = "vlc-version"..msgseperator..vlcversion..msgterminator elseif command == "get-vlc-version" then response = "vlc-version"..msgseperator..vlcversion..msgterminator
elseif command == "get-duration" then response = "duration"..msgseperator..errormerge(get_duration())..msgterminator elseif command == "get-duration" then
newduration = errormerge(get_duration())
response = "duration"..msgseperator..newduration..msgterminator
oldduration = newduration
elseif command == "get-filepath" then response = "filepath"..msgseperator..errormerge(get_filepath())..msgterminator elseif command == "get-filepath" then response = "filepath"..msgseperator..errormerge(get_filepath())..msgterminator
elseif command == "get-filename" then response = "filename"..msgseperator..errormerge(get_filename())..msgterminator elseif command == "get-filename" then response = "filename"..msgseperator..errormerge(get_filename())..msgterminator
elseif command == "get-title" then response = "title"..msgseperator..errormerge(get_var("title", 0))..msgterminator elseif command == "get-title" then response = "title"..msgseperator..errormerge(get_var("title", 0))..msgterminator

View File

@ -295,6 +295,13 @@ end
chat_timer=mp.add_periodic_timer(TICK_INTERVAL, chat_update) chat_timer=mp.add_periodic_timer(TICK_INTERVAL, chat_update)
mp.observe_property('eof-reached', 'bool', function(e)
if mp.get_property_native("eof-reached") == true then
mp.command('print-text "<eof>"')
end
end)
mp.register_script_message('chat', function(e) mp.register_script_message('chat', function(e)
add_chat(e) add_chat(e)
end) end)
@ -985,7 +992,7 @@ function readyMpvAfterSettingsKnown()
add_repl_alpharow_bindings(alpharowbindings) add_repl_alpharow_bindings(alpharowbindings)
mp.add_forced_key_binding('tab', handle_tab) mp.add_forced_key_binding('tab', handle_tab)
end end
end end
syncplayintfSet = true syncplayintfSet = true
end end
end end

View File

@ -1,463 +0,0 @@
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deftab529{\fonttbl{\f0\fswiss\fcharset0 Helvetica;}{\f1\fswiss\fcharset238 Helvetica;}}
{\colortbl ;\red0\green0\blue255;}
{\*\generator Riched20 10.0.18362}\viewkind4\uc1
\pard\tx529\f0\fs24\lang9 Syncplay relies on the following softwares, in compliance with their licenses. \par
\par
\b Qt.py\b0\par
\par
Copyright (c) 2016 Marcus Ottosson\par
\par
Permission is hereby granted, free of charge, to any person obtaining a copy\par
of this software and associated documentation files (the "Software"), to deal\par
in the Software without restriction, including without limitation the rights\par
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\par
copies of the Software, and to permit persons to whom the Software is\par
furnished to do so, subject to the following conditions:\par
\par
The above copyright notice and this permission notice shall be included in all\par
copies or substantial portions of the Software.\par
\par
\b Qt for Python\par
\b0\par
Copyright (C) 2018 The Qt Company Ltd.\par
Contact: {{\field{\*\fldinst{HYPERLINK https://www.qt.io/licensing/ }}{\fldrslt{https://www.qt.io/licensing/\ul0\cf0}}}}\f0\fs24\par
\par
This program is free software: you can redistribute it and/or modify\par
it under the terms of the GNU Lesser General Public License as published\par
by the Free Software Foundation, either version 3 of the License, or\par
(at your option) any later version.\par
\par
This program is distributed in the hope that it will be useful,\par
but WITHOUT ANY WARRANTY; without even the implied warranty of\par
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\par
GNU Lesser General Public License for more details.\par
\par
You should have received a copy of the GNU Lesser General Public License\par
along with this program. If not, see <{{\field{\*\fldinst{HYPERLINK "http://www.gnu.org/licenses/"}}{\fldrslt{http://www.gnu.org/licenses/\ul0\cf0}}}}\f0\fs24 >.\par
\par
\b Qt\b0\par
\par
This program uses Qt under the GNU LGPL version 3.\par
\par
Qt is a C++ toolkit for cross-platform application development.\par
\par
Qt provides single-source portability across all major desktop operating systems. It is also available for embedded Linux and other embedded and mobile operating systems.\par
\par
Qt is available under three different licensing options designed to accommodate the needs of our various users.\par
\par
Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 3 or GNU LGPL version 2.1.\par
\par
Qt licensed under the GNU LGPL version 3 is appropriate for the development of Qt applications provided you can comply with the terms and conditions of the GNU LGPL version 3.\par
\par
Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications provided you can comply with the terms and conditions of the GNU LGPL version 2.1.\par
\par
Please see qt.io/licensing for an overview of Qt licensing.\par
\par
Copyright (C) 2017 The Qt Company Ltd and other contributors.\par
\par
Qt and the Qt logo are trademarks of The Qt Company Ltd.\par
\par
Qt is The Qt Company Ltd product developed as an open source project. See qt.io for more information.\par
\par
\b Twisted\par
\par
\b0 Copyright (c) 2001-2017\par
Allen Short\par
Amber Hawkie Brown\par
Andrew Bennetts\par
Andy Gayton\par
Antoine Pitrou\par
Apple Computer, Inc.\par
Ashwini Oruganti\par
Benjamin Bruheim\par
Bob Ippolito\par
Canonical Limited\par
Christopher Armstrong\par
David Reid\par
Divmod Inc.\par
Donovan Preston\par
Eric Mangold\par
Eyal Lotem\par
Google Inc.\par
Hybrid Logic Ltd.\par
Hynek Schlawack\par
Itamar Turner-Trauring\par
James Knight\par
Jason A. Mobarak\par
Jean-Paul Calderone\par
Jessica McKellar\par
Jonathan D. Simms\par
Jonathan Jacobs\par
Jonathan Lange\par
Julian Berman\par
J\'fcrgen Hermann\par
Kevin Horn\par
Kevin Turner\par
Laurens Van Houtven\par
Mary Gardiner\par
Massachusetts Institute of Technology\par
Matthew Lefkowitz\par
Moshe Zadka\par
Paul Swartz\par
Pavel Pergamenshchik\par
Rackspace, US Inc.\par
Ralph Meijer\par
Richard Wall\par
Sean Riley\par
Software Freedom Conservancy\par
Tavendo GmbH\par
Thijs Triemstra\par
Thomas Herve\par
Timothy Allen\par
Tom Prince\par
Travis B. Hartwell\par
\par
and others that have contributed code to the public domain.\par
\par
Permission is hereby granted, free of charge, to any person obtaining\par
a copy of this software and associated documentation files (the\par
"Software"), to deal in the Software without restriction, including\par
without limitation the rights to use, copy, modify, merge, publish,\par
distribute, sublicense, and/or sell copies of the Software, and to\par
permit persons to whom the Software is furnished to do so, subject to\par
the following conditions:\par
\par
The above copyright notice and this permission notice shall be\par
included in all copies or substantial portions of the Software.\par
\b\par
qt5reactor\par
\par
\b0 Copyright (c) 2001-2018\par
Allen Short\par
Andy Gayton\par
Andrew Bennetts\par
Antoine Pitrou\par
Apple Computer, Inc.\par
Ashwini Oruganti\par
bakbuk\par
Benjamin Bruheim\par
Bob Ippolito\par
Burak Nehbit\par
Canonical Limited\par
Christopher Armstrong\par
Christopher R. Wood\par
David Reid\par
Donovan Preston\par
Elvis Stansvik\par
Eric Mangold\par
Eyal Lotem\par
Glenn Tarbox\par
Google Inc.\par
Hybrid Logic Ltd.\par
Hynek Schlawack\par
Itamar Turner-Trauring\par
James Knight\par
Jason A. Mobarak\par
Jean-Paul Calderone\par
Jessica McKellar\par
Jonathan Jacobs\par
Jonathan Lange\par
Jonathan D. Simms\par
J\'fcrgen Hermann\par
Julian Berman\par
Kevin Horn\par
Kevin Turner\par
Kyle Altendorf\par
Laurens Van Houtven\par
Mary Gardiner\par
Matthew Lefkowitz\par
Massachusetts Institute of Technology\par
Moshe Zadka\par
Paul Swartz\par
Pavel Pergamenshchik\par
Ralph Meijer\par
Richard Wall\par
Sean Riley\par
Software Freedom Conservancy\par
Tarashish Mishra\par
Travis B. Hartwell\par
Thijs Triemstra\par
Thomas Herve\par
Timothy Allen\par
Tom Prince\par
\par
Permission is hereby granted, free of charge, to any person obtaining\par
a copy of this software and associated documentation files (the\par
"Software"), to deal in the Software without restriction, including\par
without limitation the rights to use, copy, modify, merge, publish,\par
distribute, sublicense, and/or sell copies of the Software, and to\par
permit persons to whom the Software is furnished to do so, subject to\par
the following conditions:\par
\par
The above copyright notice and this permission notice shall be\par
included in all copies or substantial portions of the Software.\par
\par
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\par
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\par
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\par
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\par
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\par
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\par
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\b\par
\par
appnope\par
\b0\par
Copyright (c) 2013, Min Ragan-Kelley\par
\par
All rights reserved.\par
\par
Redistribution and use in source and binary forms, with or without\par
modification, are permitted provided that the following conditions are met:\par
\par
Redistributions of source code must retain the above copyright notice, this\par
list of conditions and the following disclaimer.\par
\par
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\par
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\par
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\par
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE\par
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\par
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\par
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\par
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\par
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\par
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\par
\par
\b py2exe\par
\b0\par
Copyright (c) 2000-2013 Thomas Heller, Jimmy Retzlaff\par
\par
Permission is hereby granted, free of charge, to any person obtaining\par
a copy of this software and associated documentation files (the\par
"Software"), to deal in the Software without restriction, including\par
without limitation the rights to use, copy, modify, merge, publish,\par
distribute, sublicense, and/or sell copies of the Software, and to\par
permit persons to whom the Software is furnished to do so, subject to\par
the following conditions:\par
\par
The above copyright notice and this permission notice shall be\par
included in all copies or substantial portions of the Software.\par
\par
\b py2app\par
\par
\b0 Copyright (c) 2004 Bob Ippolito.\par
\par
Some parts copyright (c) 2010-2014 Ronald Oussoren\par
\par
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\par
\par
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\par
\par
\b dmgbuild\par
\par
\b0 Copyright (c) 2014 Alastair Houghton\par
Copyright (c) 2017 The Qt Company Ltd.\par
\par
Permission is hereby granted, free of charge, to any person obtaining a copy\par
of this software and associated documentation files (the "Software"), to deal\par
in the Software without restriction, including without limitation the rights\par
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\par
copies of the Software, and to permit persons to whom the Software is\par
furnished to do so, subject to the following conditions:\par
\par
The above copyright notice and this permission notice shall be included in\par
all copies or substantial portions of the Software.\par
\par
\b Requests\par
\par
\b0 Copyright 2018 Kenneth Reitz\par
\par
Licensed under the Apache License, Version 2.0 (the \ldblquote License\rdblquote ); you may not use this file\par
except in compliance with the License. You may obtain a copy of the License at\par
\par
{{\field{\*\fldinst{HYPERLINK http://www.apache.org/licenses/LICENSE-2.0 }}{\fldrslt{http://www.apache.org/licenses/LICENSE-2.0\ul0\cf0}}}}\f0\fs24\par
\par
Unless required by applicable law or agreed to in writing, software distributed under the \par
License is distributed on an \ldblquote AS IS\rdblquote BASIS, WITHOUT WARRANTIES OR CONDI-\par
TIONS OF ANY KIND, either express or implied. See the License for the specific lang-\par
uage governing permissions and limitations under the License.\par
\par
\b mpv-repl\b0\par
\par
Copyright 2016, James Ross-Gowan\par
\par
Permission to use, copy, modify, and/or distribute this software for any\par
purpose with or without fee is hereby granted, provided that the above\par
copyright notice and this permission notice appear in all copies.\par
\par
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\par
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\par
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\par
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\par
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\par
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\par
PERFORMANCE OF THIS SOFTWARE.\par
\par
\b python-certifi\b0\par
\par
This Source Code Form is subject to the terms of the Mozilla Public License,\par
v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain\par
one at {{\field{\*\fldinst{HYPERLINK http://mozilla.org/MPL/2.0/ }}{\fldrslt{http://mozilla.org/MPL/2.0/\ul0\cf0}}}}\f0\fs24 .\par
\par
\b cffi\b0\par
\par
\pard This package has been mostly done by Armin Rigo with help from\par
Maciej Fija\f1\'b3kowski. The idea is heavily based (although not directly\par
copied) from LuaJIT ffi by Mike Pall.\par
\par
Other contributors:\par
\par
Google Inc.\par
\pard\tx529\par
The MIT License\par
\par
Permission is hereby granted, free of charge, to any person \par
obtaining a copy of this software and associated documentation \par
files (the "Software"), to deal in the Software without \par
restriction, including without limitation the rights to use, \par
copy, modify, merge, publish, distribute, sublicense, and/or \par
sell copies of the Software, and to permit persons to whom the \par
Software is furnished to do so, subject to the following conditions:\par
\par
The above copyright notice and this permission notice shall be included \par
in all copies or substantial portions of the Software.\par
\par
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS \par
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \par
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL \par
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \par
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING \par
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER \par
DEALINGS IN THE SOFTWARE.\par
\par
\b service-identity\b0\par
\par
Copyright (c) 2014 Hynek Schlawack\par
\par
Permission is hereby granted, free of charge, to any person obtaining a copy of\par
this software and associated documentation files (the "Software"), to deal in\par
the Software without restriction, including without limitation the rights to\par
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\par
of the Software, and to permit persons to whom the Software is furnished to do\par
so, subject to the following conditions:\par
\par
The above copyright notice and this permission notice shall be included in all\par
copies or substantial portions of the Software.\par
\par
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\par
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\par
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\par
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\par
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\par
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\par
SOFTWARE.\par
\par
\b pyopenssl\b0\par
\par
Licensed under the Apache License, Version 2.0 (the \ldblquote License\rdblquote ); you may not use this file\par
except in compliance with the License. You may obtain a copy of the License at\par
\par
{{\field{\*\fldinst{HYPERLINK http://www.apache.org/licenses/LICENSE-2.0 }}{\fldrslt{http://www.apache.org/licenses/LICENSE-2.0\ul0\cf0}}}}\f1\fs24\par
\par
Unless required by applicable law or agreed to in writing, software distributed under the \par
License is distributed on an \ldblquote AS IS\rdblquote BASIS, WITHOUT WARRANTIES OR CONDI-\par
TIONS OF ANY KIND, either express or implied. See the License for the specific lang-\par
uage governing permissions and limitations under the License.\par
\par
\b cryptography\b0\par
\par
Authors listed here: {{\field{\*\fldinst{HYPERLINK https://github.com/pyca/cryptography/blob/master/AUTHORS.rst }}{\fldrslt{https://github.com/pyca/cryptography/blob/master/AUTHORS.rst\ul0\cf0}}}}\f1\fs24\par
\par
Licensed under the Apache License, Version 2.0 (the \ldblquote License\rdblquote ); you may not use this file\par
except in compliance with the License. You may obtain a copy of the License at\par
\par
{{\field{\*\fldinst{HYPERLINK http://www.apache.org/licenses/LICENSE-2.0 }}{\fldrslt{http://www.apache.org/licenses/LICENSE-2.0\ul0\cf0}}}}\f1\fs24\par
\par
Unless required by applicable law or agreed to in writing, software distributed under the \par
License is distributed on an \ldblquote AS IS\rdblquote BASIS, WITHOUT WARRANTIES OR CONDI-\par
TIONS OF ANY KIND, either express or implied. See the License for the specific lang-\par
uage governing permissions and limitations under the License.\par
\par
\b Darkdetect\b0\par
\par
Copyright (c) 2019, Alberto Sottile\par
All rights reserved.\par
\par
Redistribution and use in source and binary forms, with or without\par
modification, are permitted provided that the following conditions are met:\par
* Redistributions of source code must retain the above copyright\par
notice, this list of conditions and the following disclaimer.\par
* Redistributions in binary form must reproduce the above copyright\par
notice, this list of conditions and the following disclaimer in the\par
documentation and/or other materials provided with the distribution.\par
* Neither the name of "darkdetect" nor the\par
names of its contributors may be used to endorse or promote products\par
derived from this software without specific prior written permission.\par
\par
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\par
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\par
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\par
DISCLAIMED. IN NO EVENT SHALL "Alberto Sottile" BE LIABLE FOR ANY\par
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\par
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\par
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\par
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\par
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\par
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\par
\par
\b Python MPV JSONIPC\par
\b0\f0\lang2057 Authors listed here: {{\field{\*\fldinst{HYPERLINK https://github.com/iwalton3/python-mpv-jsonipc/ }}{\fldrslt{https://github.com/iwalton3/python-mpv-jsonipc/\ul0\cf0}}}}\f0\fs24 (principal developer Ian Walton / iwalton3)\b\f1\lang9\par
\par
\b0 Licensed under the Apache License, Version 2.0 (the \ldblquote License\rdblquote ); you may not use this file\par
except in compliance with the License. You may obtain a copy of the License at\par
\par
{{\field{\*\fldinst{HYPERLINK http://www.apache.org/licenses/LICENSE-2.0 }}{\fldrslt{http://www.apache.org/licenses/LICENSE-2.0\ul0\cf0}}}}\f1\fs24\par
\par
Unless required by applicable law or agreed to in writing, software distributed under the \par
License is distributed on an \ldblquote AS IS\rdblquote BASIS, WITHOUT WARRANTIES OR CONDI-\par
TIONS OF ANY KIND, either express or implied. See the License for the specific lang-\par
uage governing permissions and limitations under the License.\par
\b\par
\par
Icons\par
\par
\b0 Syncplay uses the following icons and images:\par
\par
- Silk icon set 1.3\par
_________________________________________\par
Mark James\par
{{\field{\*\fldinst{HYPERLINK http://www.famfamfam.com/lab/icons/silk/ }}{\fldrslt{http://www.famfamfam.com/lab/icons/silk/\ul0\cf0}}}}\f1\fs24\par
_________________________________________\par
\par
This work is licensed under a\par
Creative Commons Attribution 2.5 License.\par
[ {{\field{\*\fldinst{HYPERLINK http://creativecommons.org/licenses/by/2.5/ }}{\fldrslt{http://creativecommons.org/licenses/by/2.5/\ul0\cf0}}}}\f1\fs24 ]\par
\par
This means you may use it for any purpose,\par
and make any changes you like.\par
All I ask is that you include a link back\par
to this page in your credits.\par
\par
Are you using this icon set? Send me an email\par
(including a link or picture if available) to\par
mjames@gmail.com\par
\par
Any other questions about this icon set please\par
contact mjames@gmail.com\par
\par
- Silk Companion 1\par
\par
\pard Copyright Damien Guard - CC-BY 3.0\par
{{\field{\*\fldinst{HYPERLINK https://damieng.com/creative/icons/silk-companion-1-icons }}{\fldrslt{https://damieng.com/creative/icons/silk-companion-1-icons\ul0\cf0}}}}\f1\fs24\par
\par
- Padlock free icon\par
CC-BY 3.0\par
Icon made by Maxim Basinski from {{\field{\*\fldinst{HYPERLINK https://www.flaticon.com/free-icon/padlock_291248 }}{\fldrslt{https://www.flaticon.com/free-icon/padlock_291248\ul0\cf0}}}}\f1\fs24\par
\par
\pard\tx529\par
}

View File

@ -0,0 +1,548 @@
Syncplay relies on the following software, in compliance with their licenses.
- Python 3
Copyright © 2001-2021 Python Software Foundation; All Rights Reserved
PSF LICENSE AGREEMENT FOR PYTHON 3
1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and
the Individual or Organization ("Licensee") accessing and otherwise using Python
3 software in source or binary form and its associated documentation.
2. Subject to the terms and conditions of this License Agreement, PSF hereby
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
analyze, test, perform and/or display publicly, prepare derivative works,
distribute, and otherwise use Python 3 alone or in any derivative
version, provided, however, that PSF's License Agreement and PSF's notice of
copyright, i.e., "Copyright © 2001-2021 Python Software Foundation; All Rights
Reserved" are retained in Python 3 alone or in any derivative version
prepared by Licensee.
3. In the event Licensee prepares a derivative work that is based on or
incorporates Python 3 or any part thereof, and wants to make the
derivative work available to others as provided herein, then Licensee hereby
agrees to include in any such work a brief summary of the changes made to Python
3.
4. PSF is making Python 3 available to Licensee on an "AS IS" basis.
PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF
EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR
WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE
USE OF PYTHON 3.8.8 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 3
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF
MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 3, OR ANY DERIVATIVE
THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
6. This License Agreement will automatically terminate upon a material breach of
its terms and conditions.
7. Nothing in this License Agreement shall be deemed to create any relationship
of agency, partnership, or joint venture between PSF and Licensee. This License
Agreement does not grant permission to use PSF trademarks or trade name in a
trademark sense to endorse or promote products or services of Licensee, or any
third party.
8. By copying, installing or otherwise using Python 3 Licensee agrees
to be bound by the terms and conditions of this License Agreement.
Further notices regarding the Python Standard Library can be found at
https://docs.python.org/3.8/license.html
#########################################################################################
- Qt.py
Copyright (c) 2016 Marcus Ottosson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
#########################################################################################
- Qt for Python
Copyright (C) 2018 The Qt Company Ltd.
Contact: https://www.qt.io/licensing/
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
#########################################################################################
- Qt
This program uses Qt under the GNU LGPL version 3.
Qt is a C++ toolkit for cross-platform application development.
Qt provides single-source portability across all major desktop operating systems. It is
also available for embedded Linux and other embedded and mobile operating systems.
Qt is available under three different licensing options designed to accommodate the needs
of our various users.
Qt licensed under our commercial license agreement is appropriate for development of
proprietary/commercial software where you do not want to share any source code with third
parties or otherwise cannot comply with the terms of the GNU LGPL version 3 or GNU LGPL
version 2.1.
Qt licensed under the GNU LGPL version 3 is appropriate for the development of Qt applications
provided you can comply with the terms and conditions of the GNU LGPL version 3.
Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt
applications provided you can comply with the terms and conditions of the GNU LGPL version 2.1.
Please see qt.io/licensing for an overview of Qt licensing.
Copyright (C) 2017 The Qt Company Ltd and other contributors.
Qt and the Qt logo are trademarks of The Qt Company Ltd.
Qt is The Qt Company Ltd product developed as an open source project. See qt.io for more information.
#########################################################################################
- Twisted
Copyright (c) 2001-2017
Allen Short
Amber Hawkie Brown
Andrew Bennetts
Andy Gayton
Antoine Pitrou
Apple Computer, Inc.
Ashwini Oruganti
Benjamin Bruheim
Bob Ippolito
Canonical Limited
Christopher Armstrong
David Reid
Divmod Inc.
Donovan Preston
Eric Mangold
Eyal Lotem
Google Inc.
Hybrid Logic Ltd.
Hynek Schlawack
Itamar Turner-Trauring
James Knight
Jason A. Mobarak
Jean-Paul Calderone
Jessica McKellar
Jonathan D. Simms
Jonathan Jacobs
Jonathan Lange
Julian Berman
Jürgen Hermann
Kevin Horn
Kevin Turner
Laurens Van Houtven
Mary Gardiner
Massachusetts Institute of Technology
Matthew Lefkowitz
Moshe Zadka
Paul Swartz
Pavel Pergamenshchik
Rackspace, US Inc.
Ralph Meijer
Richard Wall
Sean Riley
Software Freedom Conservancy
Tavendo GmbH
Thijs Triemstra
Thomas Herve
Timothy Allen
Tom Prince
Travis B. Hartwell
and others that have contributed code to the public domain.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
#########################################################################################
- qt5reactor
Copyright (c) 2001-2018
Allen Short
Andy Gayton
Andrew Bennetts
Antoine Pitrou
Apple Computer, Inc.
Ashwini Oruganti
bakbuk
Benjamin Bruheim
Bob Ippolito
Burak Nehbit
Canonical Limited
Christopher Armstrong
Christopher R. Wood
David Reid
Donovan Preston
Elvis Stansvik
Eric Mangold
Eyal Lotem
Glenn Tarbox
Google Inc.
Hybrid Logic Ltd.
Hynek Schlawack
Itamar Turner-Trauring
James Knight
Jason A. Mobarak
Jean-Paul Calderone
Jessica McKellar
Jonathan Jacobs
Jonathan Lange
Jonathan D. Simms
Jürgen Hermann
Julian Berman
Kevin Horn
Kevin Turner
Kyle Altendorf
Laurens Van Houtven
Mary Gardiner
Matthew Lefkowitz
Massachusetts Institute of Technology
Moshe Zadka
Paul Swartz
Pavel Pergamenshchik
Ralph Meijer
Richard Wall
Sean Riley
Software Freedom Conservancy
Tarashish Mishra
Travis B. Hartwell
Thijs Triemstra
Thomas Herve
Timothy Allen
Tom Prince
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#########################################################################################
- appnope
Copyright (c) 2013, Min Ragan-Kelley
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#########################################################################################
- py2exe
Copyright (c) 2000-2013 Thomas Heller, Jimmy Retzlaff
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
#########################################################################################
- py2app
Copyright (c) 2004 Bob Ippolito.
Some parts copyright (c) 2010-2014 Ronald Oussoren
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#########################################################################################
- dmgbuild
Copyright (c) 2014 Alastair Houghton
Copyright (c) 2017 The Qt Company Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
#########################################################################################
- Requests
Copyright 2018 Kenneth Reitz
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file
except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the
License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDI-
TIONS OF ANY KIND, either express or implied. See the License for the specific lang-
uage governing permissions and limitations under the License.
#########################################################################################
- mpv-repl
Copyright 2016, James Ross-Gowan
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
#########################################################################################
- python-certifi
This Source Code Form is subject to the terms of the Mozilla Public License,
v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain
one at http://mozilla.org/MPL/2.0/.
#########################################################################################
- cffi
This package has been mostly done by Armin Rigo with help from
Maciej Fijałkowski. The idea is heavily based (although not directly
copied) from LuaJIT ffi by Mike Pall.
Other contributors:
Google Inc.
The MIT License
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
#########################################################################################
- service-identity
Copyright (c) 2014 Hynek Schlawack
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
#########################################################################################
- pyopenssl
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file
except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the
License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDI-
TIONS OF ANY KIND, either express or implied. See the License for the specific lang-
uage governing permissions and limitations under the License.
#########################################################################################
- cryptography
Authors listed here: https://github.com/pyca/cryptography/blob/master/AUTHORS.rst
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file
except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the
License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDI-
TIONS OF ANY KIND, either express or implied. See the License for the specific lang-
uage governing permissions and limitations under the License.
#########################################################################################
- Darkdetect
Copyright (c) 2019, Alberto Sottile
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of "darkdetect" nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL "Alberto Sottile" BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#########################################################################################
- Python MPV JSONIPC
Authors listed here: https://github.com/iwalton3/python-mpv-jsonipc/ (principal developer Ian Walton / iwalton3)
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file
except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the
License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDI-
TIONS OF ANY KIND, either express or implied. See the License for the specific lang-
uage governing permissions and limitations under the License.
#########################################################################################
- Icons
Syncplay uses the following icons and images:
- Silk icon set 1.3
_________________________________________
Mark James
http://www.famfamfam.com/lab/icons/silk/
_________________________________________
This work is licensed under a
Creative Commons Attribution 2.5 License.
[ http://creativecommons.org/licenses/by/2.5/ ]
This means you may use it for any purpose,
and make any changes you like.
All I ask is that you include a link back
to this page in your credits.
Are you using this icon set? Send me an email
(including a link or picture if available) to
mjames@gmail.com
Any other questions about this icon set please
contact mjames@gmail.com
- Silk Companion 1
Copyright Damien Guard - CC-BY 3.0
https://damieng.com/creative/icons/silk-companion-1-icons
- Padlock free icon
CC-BY 3.0
Icon made by Maxim Basinski from https://www.flaticon.com/free-icon/padlock_291248

View File

@ -190,9 +190,9 @@ class AboutDialog(QtWidgets.QDialog):
def openDependencies(self): def openDependencies(self):
if isWindows(): if isWindows():
QtGui.QDesktopServices.openUrl(QUrl("file:///" + resourcespath + "third-party-notices.rtf")) QtGui.QDesktopServices.openUrl(QUrl("file:///" + resourcespath + "third-party-notices.txt"))
else: else:
QtGui.QDesktopServices.openUrl(QUrl("file://" + resourcespath + "third-party-notices.rtf")) QtGui.QDesktopServices.openUrl(QUrl("file://" + resourcespath + "third-party-notices.txt"))
class CertificateDialog(QtWidgets.QDialog): class CertificateDialog(QtWidgets.QDialog):

View File

@ -38,7 +38,7 @@ class MPVError(Exception):
class WindowsSocket(threading.Thread): class WindowsSocket(threading.Thread):
""" """
Wraps a Windows named pipe in a high-level interface. (Internal) Wraps a Windows named pipe in a high-level interface. (Internal)
Data is automatically encoded and decoded as JSON. The callback Data is automatically encoded and decoded as JSON. The callback
function will be called for each inbound message. function will be called for each inbound message.
""" """
@ -52,7 +52,7 @@ class WindowsSocket(threading.Thread):
ipc_socket = "\\\\.\\pipe\\" + ipc_socket ipc_socket = "\\\\.\\pipe\\" + ipc_socket
self.callback = callback self.callback = callback
self.quit_callback = quit_callback self.quit_callback = quit_callback
access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE
limit = 5 # Connection may fail at first. Try 5 times. limit = 5 # Connection may fail at first. Try 5 times.
for _ in range(limit): for _ in range(limit):
@ -112,11 +112,15 @@ class WindowsSocket(threading.Thread):
except EOFError: except EOFError:
if self.quit_callback: if self.quit_callback:
self.quit_callback() self.quit_callback()
except Exception as ex:
log.error("Pipe connection died.", exc_info=1)
if self.quit_callback:
self.quit_callback()
class UnixSocket(threading.Thread): class UnixSocket(threading.Thread):
""" """
Wraps a Unix/Linux socket in a high-level interface. (Internal) Wraps a Unix/Linux socket in a high-level interface. (Internal)
Data is automatically encoded and decoded as JSON. The callback Data is automatically encoded and decoded as JSON. The callback
function will be called for each inbound message. function will be called for each inbound message.
""" """
@ -159,22 +163,25 @@ class UnixSocket(threading.Thread):
def run(self): def run(self):
"""Process socket events. Do not run this directly. Use *start*.""" """Process socket events. Do not run this directly. Use *start*."""
data = b'' data = b''
while True: try:
current_data = self.socket.recv(1024) while True:
if current_data == b'': current_data = self.socket.recv(1024)
break if current_data == b'':
break
data += current_data data += current_data
if data[-1] != 10: if data[-1] != 10:
continue
data = data.decode('utf-8', 'ignore').encode('utf-8')
for item in data.split(b'\n'):
if item == b'':
continue continue
json_data = json.loads(item)
self.callback(json_data) data = data.decode('utf-8', 'ignore').encode('utf-8')
data = b'' for item in data.split(b'\n'):
if item == b'':
continue
json_data = json.loads(item)
self.callback(json_data)
data = b''
except Exception as ex:
log.error("Socket connection died.", exc_info=1)
if self.quit_callback: if self.quit_callback:
self.quit_callback() self.quit_callback()
@ -196,7 +203,7 @@ class MPVProcess:
mpv_location = "mpv.exe" mpv_location = "mpv.exe"
else: else:
mpv_location = "mpv" mpv_location = "mpv"
log.debug("Staring MPV from {0}.".format(mpv_location)) log.debug("Staring MPV from {0}.".format(mpv_location))
if os.name == 'nt': if os.name == 'nt':
ipc_socket = "\\\\.\\pipe\\" + ipc_socket ipc_socket = "\\\\.\\pipe\\" + ipc_socket
@ -226,7 +233,7 @@ class MPVProcess:
else: else:
self.process.terminate() self.process.terminate()
raise MPVError("MPV start timed out.") raise MPVError("MPV start timed out.")
if not ipc_exists or self.process.returncode is not None: if not ipc_exists or self.process.returncode is not None:
self.process.terminate() self.process.terminate()
raise MPVError("MPV not started.") raise MPVError("MPV not started.")
@ -278,7 +285,7 @@ class MPVInter:
self.quit_callback = quit_callback self.quit_callback = quit_callback
if self.callback is None: if self.callback is None:
self.callback = lambda event, data: None self.callback = lambda event, data: None
self.socket = Socket(ipc_socket, self.event_callback, self.quit_callback) self.socket = Socket(ipc_socket, self.event_callback, self.quit_callback)
self.socket.start() self.socket.start()
self.command_id = 1 self.command_id = 1
@ -286,7 +293,7 @@ class MPVInter:
self.socket_lock = threading.Lock() self.socket_lock = threading.Lock()
self.cid_result = {} self.cid_result = {}
self.cid_wait = {} self.cid_wait = {}
def stop(self, join=True): def stop(self, join=True):
"""Terminate the underlying connection.""" """Terminate the underlying connection."""
self.socket.stop(join) self.socket.stop(join)
@ -298,11 +305,11 @@ class MPVInter:
self.cid_wait[data["request_id"]].set() self.cid_wait[data["request_id"]].set()
elif "event" in data: elif "event" in data:
self.callback(data["event"], data) self.callback(data["event"], data)
def command(self, command, *args): def command(self, command, *args):
""" """
Issue a command to MPV. Will block until completed or timeout is reached. Issue a command to MPV. Will block until completed or timeout is reached.
*command* is the name of the MPV command *command* is the name of the MPV command
All further arguments are forwarded to the MPV command. All further arguments are forwarded to the MPV command.
@ -344,13 +351,13 @@ class EventHandler(threading.Thread):
"""Create an instance of the thread.""" """Create an instance of the thread."""
self.queue = queue.Queue() self.queue = queue.Queue()
threading.Thread.__init__(self) threading.Thread.__init__(self)
def put_task(self, func, *args): def put_task(self, func, *args):
""" """
Put a new task to the thread. Put a new task to the thread.
*func* is the function to call *func* is the function to call
All further arguments are forwarded to *func*. All further arguments are forwarded to *func*.
""" """
self.queue.put((func, args)) self.queue.put((func, args))
@ -374,10 +381,10 @@ class EventHandler(threading.Thread):
class MPV: class MPV:
""" """
The main MPV interface class. Use this to control MPV. The main MPV interface class. Use this to control MPV.
This will expose all mpv commands as callable methods and all properties. This will expose all mpv commands as callable methods and all properties.
You can set properties and call the commands directly. You can set properties and call the commands directly.
Please note that if you are using a really old MPV version, a fallback command Please note that if you are using a really old MPV version, a fallback command
list is used. Not all commands may actually work when this fallback is used. list is used. Not all commands may actually work when this fallback is used.
""" """
@ -431,7 +438,7 @@ class MPV:
self.observer_lock = threading.Lock() self.observer_lock = threading.Lock()
self.keybind_id = 1 self.keybind_id = 1
self.keybind_lock = threading.Lock() self.keybind_lock = threading.Lock()
if log_handler is not None and loglevel is not None: if log_handler is not None and loglevel is not None:
self.command("request_log_messages", loglevel) self.command("request_log_messages", loglevel)
@self.on_event("log-message") @self.on_event("log-message")
@ -570,7 +577,7 @@ class MPV:
self.bind_property_observer(name, func) self.bind_property_observer(name, func)
return func return func
return wrapper return wrapper
def wait_for_property(self, name): def wait_for_property(self, name):
""" """
Waits for the value of a property to change. Waits for the value of a property to change.
@ -618,11 +625,11 @@ class MPV:
""" """
Send a command to MPV. All commands are bound to the class by default, Send a command to MPV. All commands are bound to the class by default,
except JSON IPC specific commands. This may also be useful to retain except JSON IPC specific commands. This may also be useful to retain
compatibility with python-mpv, as it does not bind all of the commands. compatibility with python-mpv, as it does not bind all of the commands.
*command* is the command name. *command* is the command name.
All further arguments are forwarded to the MPV command. All further arguments are forwarded to the MPV command.
""" """
return self.mpv_inter.command(command, *args) return self.mpv_inter.command(command, *args)

View File

@ -6,7 +6,7 @@ with open("README.md", "r") as fh:
setup( setup(
name='python-mpv-jsonipc', name='python-mpv-jsonipc',
version='1.1.11', version='1.1.13',
author="Ian Walton", author="Ian Walton",
author_email="iwalton3@gmail.com", author_email="iwalton3@gmail.com",
description="Python API to MPV using JSON IPC", description="Python API to MPV using JSON IPC",