Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On MacOS Ventura; Error: "Failed to recognize file format" when attempting to play any YouTube video #585

Open
PuffyRainbowCloud opened this issue Feb 4, 2023 · 16 comments
Labels
bug / problem help wanted Anyone willing to help can fix/implement this macOS

Comments

@PuffyRainbowCloud
Copy link

Describe the bug
When attempts are made to play a YouTube video on either of my machines running macOS Ventura using MPV I receive the error message "Failed to recognize file format" and nothing plays. I can play the same videos fine using SyncPlay and MPV on Windows 10. This applies to SyncPlay version 1.6.8, 1.6.9, and 1.7 Beta 1.

To Reproduce
Steps to reproduce the behavior:

  1. Launch SyncPlay.
  2. Fill out relevant server- and room information.
  3. Choose MPV as the video player.
  4. Attempt to play a YouTube URL via any of the methods within the UI of MPV or SyncPlay.

Expected behavior
The linked YouTube video should start playing.

Version and platform:

  • OS: macOS Ventura 13.0
  • Syncplay version and build type: Syncplay 1.6.8
  • Media player and version: MPV 0.35.0
@Et0h
Copy link
Contributor

Et0h commented Feb 5, 2023

Does it work fine if you're running mpv on its own without Syncplay? Do you have the latest version of ytdl installed?

@girlmaya
Copy link

girlmaya commented Feb 27, 2023

Does it work fine if you're running mpv on its own without Syncplay?

Yes, it plays fine in mpv. It doesnt even reach mpv from syncplay as far as i can tell. Can provide info just let me know, i would really like this fixed

Edit:

  • macOS Big Sur 11.7.3
  • Syncplay v1.7.0 beta 1
  • mpv 0.35.0

@ReeverM
Copy link

ReeverM commented Apr 25, 2023

I'm having the exact same issue on Windows 10. When I /qa it, it removes it from the queue immediately seemingly without reaching mpv (just the "x has updated the playlist" message pops up).

When I turn off shared playlists, /qa the youtube video and then turn on shared playlists again, it DOES reach mpv but returns "failed to recognize file format" but in this case does NOT remove the entry from the playlist.

I initially thought it was related to ffmpeg, so I installed that and now mpv plays pasted youtube videos fine (lua script to paste) but the playlist issue prevails.

@girlmaya
Copy link

on Windows 10.

it DOES reach mpv but returns "failed to recognize file format"

I think this is a different bug to what i'm experiencing on macOS. Not sure about the original issue creator

@suhailskhan
Copy link

Having the same issue with macOS Sonoma. My mpv is able to play from YouTube URLs without Syncplay.

  • macOS Sonoma 14.1
  • Syncplay 1.7.1 RC1
  • mpv 0.36.0
  • yt-dlp 2023.10.13

@girlmaya
Copy link

girlmaya commented Dec 4, 2023

Any update on this?

@suhailskhan
Copy link

My workaround is to substitute mpv with IINA, an mpv-based player with many enhancements made specifically for macOS. It works just fine with Syncplay.

@Et0h
Copy link
Contributor

Et0h commented Dec 20, 2023

Thanks for the workaround @suhailskhan - I've now added it to the FAQ at https://syncplay.pl/guide/trouble/ to benefit others who have the same issue.

@suhailskhan
Copy link

Out of curiosity, I looked into the problem a little more and encountered #379.

I captured a debug log using the instructions @albertosottile provided in that issue thread, and interestingly the log appeared to similar to the one presented in the thread. Even though the logs are similar, this earlier issue ended up being resolved in an earlier release of Syncplay. I will leave my log at the end of this comment.

Here is my system and the versions of all the software I tested with:

  • macOS Sonoma 14.4.1 (arm64)
  • Syncplay 1.7.1
  • mpv 0.37.0 (x86 build, installed with Homebrew as a cask)
  • Python 3.12.2 (installed with MacPorts at /opt/local)
  • yt-dlp 2024.03.10 (installed with pipx at ~/.local)
[17:59:25] player << Python path configuration:
[17:59:25] player << PYTHONHOME = '/Applications/Syncplay.app/Contents/Resources'
[17:59:25] player << PYTHONPATH = '/Applications/Syncplay.app/Contents/Resources'
[17:59:25] player << program name = '/opt/local/Library/Frameworks/Python.framework/Versions/3.12/Resources/Python.app/Contents/MacOS/Python'
[17:59:25] player << isolated = 0
[17:59:25] player << environment = 1
[17:59:25] player << user site = 1
[17:59:25] player << safe_path = 0
[17:59:25] player << import site = 1
[17:59:25] player << is in build tree = 0
[17:59:25] player << stdlib dir = '/Applications/Syncplay.app/Contents/Resources/lib/python3.12'
[17:59:25] player << sys._base_executable = '/opt/local/Library/Frameworks/Python.framework/Versions/3.12/bin/python3.12'
[17:59:25] player << sys.base_prefix = '/Applications/Syncplay.app/Contents/Resources'
[17:59:25] player << sys.base_exec_prefix = '/Applications/Syncplay.app/Contents/Resources'
[17:59:25] player << sys.platlibdir = 'lib'
[17:59:25] player << sys.executable = '/Users/suhailskhan/.local/pipx/venvs/yt-dlp/bin/python'
[17:59:25] player << sys.prefix = '/Applications/Syncplay.app/Contents/Resources'
[17:59:25] player << sys.exec_prefix = '/Applications/Syncplay.app/Contents/Resources'
[17:59:25] player << sys.path = [
[17:59:25] player << '/Applications/Syncplay.app/Contents/Resources',
[17:59:25] player << '/Applications/Syncplay.app/Contents/Resources/lib/python312.zip',
[17:59:25] player << '/Applications/Syncplay.app/Contents/Resources/lib/python3.12',
[17:59:25] player << '/Applications/Syncplay.app/Contents/Resources/lib/python3.12/lib-dynload',
[17:59:25] player << ]
[17:59:25] player << Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
[17:59:25] Not ready to send due to error
[17:59:25] <mpv> Ready to send: True
[17:59:25] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:25] <mpv> Throttling message send, so sleeping for 0.05
[17:59:25] <mpv> Throttling message send, so sleeping for 0.05
[17:59:25] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:25] <mpv> Throttling message send, so sleeping for 0.05
[17:59:26] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:26] <mpv> Throttling message send, so sleeping for 0.05
[17:59:26] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:26] <mpv> Throttling message send, so sleeping for 0.05
[17:59:26] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:26] <mpv> Throttling message send, so sleeping for 0.05
[17:59:26] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:26] <mpv> Throttling message send, so sleeping for 0.05
[17:59:26] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:26] <mpv> Throttling message send, so sleeping for 0.05
[17:59:26] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:26] <mpv> Throttling message send, so sleeping for 0.05
[17:59:26] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:26] <mpv> Throttling message send, so sleeping for 0.05
[17:59:26] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:26] <mpv> Throttling message send, so sleeping for 0.05
[17:59:26] player >> ['script-message-to', 'syncplayintf', 'get_paused_and_position']
[17:59:26] player << Python runtime state: core initialized
[17:59:26] player << ModuleNotFoundError: No module named 'encodings'
[17:59:26] player << Current thread 0x0000000200ef3240 (most recent call first):
[17:59:26] player << <no Python frame>
[17:59:26] player << youtube-dl failed: unexpected error occurred

@albertosottile
Copy link
Member

@suhailskhan The problem is that the location of the Python that runs youtube-dl(/opt/local/Library/Frameworks/Python.framework/Versions/3.12/bin/python3.12) does not match the paths foreseen in https://github.com/Syncplay/syncplay/pull/381/files. Unfortunately, it is impossible for me to guess this for all the possible configurations (and the use of pipx definitely did not facilitate this). Ultimately, I think these are subprocess bugs more than Syncplay bugs...

@stszap
Copy link

stszap commented Dec 21, 2024

I encountered this recently. My setup:

  • macOS 12.7.5 intel
  • syncplay 1.7.3
  • mpv 0.38.0
  • youtube-dl 2021.12.17
  • yt-dlp 2024.12.13

Everything is installed from brew. Looks like syncplay is trying to find youtube-dl via witch youtube-dl and extract the first line to determine python location here but mpv has switched to yt-dlp by default long ago. I was able to watch youtube via syncplay by extracting the first line of yt-dlp script (in my case it's #!/usr/local/Cellar/yt-dlp/2024.12.13/libexec/bin/python) and inserting it as the fist line into youtube-dl file (which had #!/usr/local/Cellar/youtube-dl/2021.12.17/libexec/bin/python3.11). This breaks youtube-dl but fixes syncplay. I guess if you only have yt-dlp installed then you will also have to install youtube-dl or just create a dummy file in /usr/local/bin or another directory. The easiest way to fix this (at least in my case) would be to just replace youtube-dl with yt-dlp in mpv.py, but the "right" way would probably be to determine what script mpv is using and extract python path from that.

@suhailskhan
Copy link

@suhailskhan The problem is that the location of the Python that runs youtube-dl(/opt/local/Library/Frameworks/Python.framework/Versions/3.12/bin/python3.12) does not match the paths foreseen in https://github.com/Syncplay/syncplay/pull/381/files. Unfortunately, it is impossible for me to guess this for all the possible configurations (and the use of pipx definitely did not facilitate this). Ultimately, I think these are subprocess bugs more than Syncplay bugs...

@albertosottile I see, that is fair enough. Though I must say that this Python path that you observed from my debug output is that of a Python interpreter installed with MacPorts. Much like how Homebrew puts symlinks of executables in /opt/homebrew/bin or /usr/local/bin, MacPorts makes symlinks in /opt/local/bin, as /opt/local is MacPorts’s default prefix. I completely understand that it is not feasible (and maybe not wise) to account for every possible configuration users may have, but MacPorts is a popular package manager on macOS (although probably not nearly as popular as Homebrew these days). So the direct solution would be to add /opt/local/bin to env['PATH'] in mpv.py’s if isMacOS() statement. I understand if this is something you would prefer not to do, since the existing code already addresses the least common denominator.

@albertosottile
Copy link
Member

but the "right" way would probably be to determine what script mpv is using and extract python path from that

@stszap Are you aware of any way to do so?

So the direct solution would be to add /opt/local/bin to env['PATH'] in mpv.py’s if isMacOS() statement.

@suhailskhan This is perhaps the direct solution for your configuration, but what about people that have mpv installed from MacPorts and youtube-dl installed from pip? Or downloaded from GitHub? Or a pipenv? Or people that use yt-dlp? I think you see now where this is going... Asking mpv what interpreter to use, as suggested above, might be a doable approach, but I am not aware of a way to achieve so.

@stszap
Copy link

stszap commented Dec 22, 2024

Are you aware of any way to do so?

@albertosottile After some digging I have a proof of concept. The latest release of mpv 0.39.0 added a new property user-data/mpv/ytdl/path which is accessible in lua scripts. It is only populated after mpv tries to play something using ytdl and can either be a full path or just a binary name. When I run mpv without options it is set to just yt-dlp but I can also specify a custom location like this mpv --script-opts=ytdl_hook-ytdl_path=/usr/local/bin/yt-dlp and in that case the value will be /usr/local/bin/yt-dlp.

First, create a lua file

local utils = require 'mp.utils'

local function print_property(name, value)
    print(name .. ": " .. utils.to_string(value))
end

mp.observe_property("user-data/mpv/ytdl/path", "native", print_property)

Then run mpv with that script and some URL which triggers ytdl
mpv --script=<file name from above>.lua ytdl://
It will return an error but also the path used by ytdl

$ mpv --script=test.lua ytdl://
[test] user-data/mpv/ytdl/path: nil
[ytdl_hook] ERROR: [generic] '' is not a valid URL. Set --default-search "ytsearch" (or run  yt-dlp "ytsearch:" ) to search YouTube
[test] user-data/mpv/ytdl/path: "yt-dlp"
[ytdl_hook] youtube-dl failed: unexpected error occurred
No protocol handler found to open URL ytdl://
The protocol is either unsupported, or was disabled at compile-time.
[ytdl_hook] ERROR: [generic] '' is not a valid URL. Set --default-search "ytsearch" (or run  yt-dlp "ytsearch:" ) to search YouTube
[ytdl_hook] youtube-dl failed: unexpected error occurred
Exiting... (Errors when loading file)

This is the most relevant part [test] user-data/mpv/ytdl/path: "yt-dlp" (why it is printed twice I have no idea, this is my first time using mpv with lua).

I'm not sure about how to integrate this with syncplay but the basic idea is to somehow do a test run of mpv with the same configuration as the real run but also add a lua script and use some sort of dummy URL, then extract ytdl path from the output. Maybe there is an easier way but this is all I could cobble together.

@Et0h Et0h added the help wanted Anyone willing to help can fix/implement this label Dec 27, 2024
@Et0h
Copy link
Contributor

Et0h commented Dec 27, 2024

Thanks for your continued work on this. The new mpv property in 0.39.0 seem to a move in the right direction. That said, for Syncplay to have better support for yt-dlp in this use case then either there would need to be an upstream change to allow for this to be supported in a much less hacky way or someone would need to volunteer to add support in a relatively clean and unobtrusive way and then maintain that support.

Syncplay's core functionality is to play locally stored files. Where it is easy we don't mind users allowing users to benefit from the streaming functionality provided by their media player, but where this is not reliable we generally see that as an upstream or out-of-scope issue rather. This is due to our limited resources, the need to avoid feature creep which can adversely impact on maintainability, and because this is not a feature we use and so we are not well placed to implement, test, and maintain the functionality (as well as the fact that ).

When I talk about clean and unobtrusive way I mean something along the following lines:

  1. Ensure code is straightforward and readable so that it is clear what it is actually doing.
  2. Ensure that any changes only affect the relevant operating systems that suffer from this issue.
  3. Minimise how often mpv must be run in a hacky way, e.g. by making mpv connect this way once and then put the result in the custom path for the specific mpv instance and in the future use the value from the custom path instead.
  4. Ensure backwards compatibility with pre-0.39.0 versions of mpv. For example, only try to connect to get the ytdl path if the user is running an unknown version of a 0.39.0+ version (using the current code that checks mpv version). If the feature is version-specific then there should be appropriate warnings when people try to load a streaming video using an old version of mpv.
  5. Commit to maintaining this support for the long term, e.g. to fix things if mpv changes in a way that requires Syncplay to be tweaked.

@stszap
Copy link

stszap commented Dec 28, 2024

Totally understandable. I also think that lua script solution is way too hacky. I tried a much simpler user-side fix for yt-dlp users: just symlink youtube-dl to yt-dlp (ln -s /usr/local/bin/yt-dlp /usr/local/bin/youtube-dl in my case but probably can be adapted to other installation methods). This way:

  • mpv will keep using installed yt-dlp by default as before
  • syncplay will extract the right python path from yt-dlp script (because it searches for youtube-dl and now it points to yt-dlp)
  • you won't be able to use real youtube-dl (with the default PATH at least)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug / problem help wanted Anyone willing to help can fix/implement this macOS
Projects
None yet
Development

No branches or pull requests

7 participants