Support streaming from online video services, e.g. Youtube
What feature would you like?
Add support for streaming directly from online services, like Youtube. This is probably not possible with all services, but some should work.
Describe the solution you'd like
The intention is to use yt-dlp to extract the underlying video URL, then passing that URL on via AirPlay (play_url). It's an easy solution that yields a simple API for most users. Testing it would be something like this:
atvremote -s 10.0.10.81 play_service=https://www.youtube.com/watch?v=dQw4w9WgXcQ
As play_url is used, that feature must be available.
Any other information to share?
TBD
I have started the work in #2187. Some caveats here though:
- I have not decided if I want
pyatvto depend onyt-dlp, so it is not a dependency for now and must be installed manually (an exception is raised otherwise) - pyatv will use video with best bitrate: it is not possible to request a certain quality/resolution (will be resolved later)
- Video services requiring authentication are not supported (yet)
- API is not final, might change or merge with
play_url - Would like to turn it into a feature, so the features API reports if it is supported or not
- Maybe other things...
This Is still an early attempt, but would love some feedback on this!
I can create a variant that installs yt-dlp as an optional dependency:
https://setuptools.pypa.io/en/latest/userguide/dependency_management.html#optional-dependencies
To continue with the other bullets:
- I will have to study yt-dlp a bit to see what filtering to support, e.g. resolution, video vs audio only, formats. Should also investigate if I can send additional metadata via AirPlay in this mode as I get a lot of that.
- Usernames and passwords can be saved as settings, preferably in a section separated from the protocols to allow for easier sharing amongst protocols (if/when needed).
- If I can somehow detect if a URL is supported by yt-dlp, then I can merge it with play_url. Not sure if that is easy to do. Otherwise it's probably simpler to keep this as a separate method. Drawback is however...
- Adding it as a method not implemented by protocols, would not make it into a feature, so I cannot easily report availability for it. Merging functionality with play_url solves this. A workaround would be to add functionality to bind feature availability to another feature, i.e. treat it as a feature but let the facade report the same availability as another feature, thus bypassing protocols in this case. I also have the case of yt-dlp not being installed... I can also just treat it as a feature, just implement it in AirPlay and add all the checks I want. Simplest as only AirPlay supports play_url anyways, so should maybe not overthink this too much.
Thinking about it once more... most people would like this as a transparent feature, i.e. pass a URL and let pyatv deal with it. That's what I would prefer as well. So merging with play_url sounds reasonable, but also add a flag to disable auto extraction in case it becomes a problem. I will have to check if I can validate if a URL is supported by yt-dlp though.
I can probably check if the URL is supported by yt-dlp like this:
https://github.com/yt-dlp/yt-dlp/issues/8101#issuecomment-1718341135
Just need to await if this is to be considered a stable API.
This: https://github.com/yt-dlp/yt-dlp/issues/8101#issuecomment-1719061307
Would this work playing an MP4/MKV from a NAS with something like Infuse as well? https://firecore.com/infuse
This will not add support for any new formats (MP4 is still your best bet) and will only support services supported by yt-dlp, where Infuse does not seem to be included. So in that particular case: no, it will not. But I imagine you can get the URL to media directly in Infuse somehow? Maybe even transcoded to an appropriate format? Since they have an Apple TV app, you could also opt for using launch_app with deep links instead (see https://pyatv.dev/development/apps/#app-deep-links).