pyatv icon indicating copy to clipboard operation
pyatv copied to clipboard

Support streaming from online video services, e.g. Youtube

Open postlund opened this issue 2 years ago • 9 comments

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

postlund avatar Sep 13 '23 12:09 postlund

I have started the work in #2187. Some caveats here though:

  • I have not decided if I want pyatv to depend on yt-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!

postlund avatar Sep 13 '23 12:09 postlund

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

postlund avatar Sep 13 '23 17:09 postlund

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.

postlund avatar Sep 13 '23 17:09 postlund

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.

postlund avatar Sep 13 '23 17:09 postlund

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.

postlund avatar Sep 14 '23 03:09 postlund

This: https://github.com/yt-dlp/yt-dlp/issues/8101#issuecomment-1719061307

postlund avatar Sep 14 '23 12:09 postlund

Would this work playing an MP4/MKV from a NAS with something like Infuse as well? https://firecore.com/infuse

robloh avatar Sep 26 '23 17:09 robloh

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).

postlund avatar Sep 26 '23 19:09 postlund