jellyfin / Swiftfin

Native Jellyfin Client for iOS and tvOS
Mozilla Public License 2.0
2.46k stars 271 forks source link

Native Video Player #308

Closed perrinpagess closed 2 years ago

perrinpagess commented 2 years ago

Describe the feature you'd like

I want an option to use AVPlayer for direct HLS instead of going through VLCKit. A toggle under "advanced settings" would be nice because it has some limitations.

Additional context

AVPlayer uses Apple's "EDR" tone mapping implementation for HDR playback on SDR and HDR displays. AVPlayer's HDR tone mapping is substantially better quality than VLCKit. AVPlayer natively supports surround audio for spatial audio processing and head tracking. Picture in picture support is native with AVPlayer as well. AVPlayer's surround to stereo mixdown is better than anything ffmpeg can do (from my testing).

I made a rudimentary video player in swift playgrounds to help demonstrate what I want (see screenshot). Instead of the url I used for the demo it would be the HLS url for a video on my Jellyfin server.

Thanks!

IMG_0034

LePips commented 2 years ago

I did implement the native player during my video player refactoring however I removed it due to navigation issue with selecting subtitles and such. It was just too much work at the moment.

We also need to build the proper direct play profiles for using the native player. That will push this back a lot.

I have thought to re-implement it and the work is in git history. This however made me think to create another setting where the AVPlayer layer is the rendering view for the video and we can use the same VLCKit overlay.

I'll first re-implement the native players as a part of this.

perrinpagess commented 2 years ago

What was the issue with subtitles? My demonstration had the ability to pick subtitles with no extra work. Safari's current implementation of the native video player allows me to pick subtitles as well. HLS specification requires WebVTT subtitle format.

What are direct play profiles required for? All my video files are sanitized and use Apple's HLS authoring approved codecs in MP4 container with proper headers. My MP4 files stream flawlessly in Safari when I copy a link from Jellyfin.

LePips commented 2 years ago

There's a lot at play here. Most people's media aren't nice and the webvtt subtitle streams aren't consistent from the server, so we have to build the native player around that. For most, this would force embedding subtitles that they would choose before they play the media. Or in your case, you would be able to choose not to embed any subtitles and choose to play them from the stream instead.

perrinpagess commented 2 years ago

I understand that most people don't want to learn how to use ffmpeg to make their files HLS compliant. I suggested hiding a toggle in "advanced settings" or whatever so that you wouldn't have to do all the extra work to make native player play nice with non-HLS compliant files.

I am fine using Safari for video streaming; however, my original intent was to suggest an enhancement that's only useful for advanced users to keep initial development work to a minimum. The native video player function could be improved in the future or just kept barebones.

LePips commented 2 years ago

Of course I'll provide the option.

This has me thinking though, people might prefer the native video player, especially on tvOS since it feels a bit nicer.

Are there tutorials on making content hls compliant? That would make a great plugin

perrinpagess commented 2 years ago

https://developer.apple.com/documentation/http_live_streaming/hls_authoring_specification_for_apple_devices

I don't know of any tutorial...I had to figure out all this stuff myself. I am willing to put in time to help make a plugin. The link above is a good write up by Apple. It's a necessary read (IMO), but also lengthy so I can give some key points.

LePips commented 2 years ago

Thanks! I do think a plugin would be awesome in the long run.

Would you be able to supply me a script for now for my own testing?

perrinpagess commented 2 years ago

Sure, every video file has a different video/audio/subtitle track order so you will have to use ffprobe and the "map" command to make sure you're copying/encoding the correct tracks. Remove "-tag:v hvc1" from the script if you're working with H.264 video or else ffmpeg will give an error. Video transcoding takes ages, the quality is never as good as the source, and my networking setup is capable of gigabit speeds through wifi, so I don't bother with it.

I like using this video for testing HDR10: https://4kmedia.org/sony-swordsmith-hdr-uhd-4k-demo/

This Dolby Vision file works with no manipulation: http://media.developer.dolby.com/DolbyVision_Atmos/mp4/iOS_P5_GlassBlowing2_3840x2160%4059.94fps_15200kbps.mp4

If your audio and subtitles are already in a compatible format and it's an HEVC video stream: ffmpeg -i input.mkv -c copy -tag:v hvc1 -map 0:v:0 -map 0:a:0 -map 0:s:0 -map_chapters -1 output.mp4

If audio isn't in a compatible format (something like dts and there's no secondary AC3 stream) and it's an HEVC video stream: ffmpeg -i input.mkv -c:v copy -tag:v hvc1 -c:a ac3 -b:a 640k -c:s copy -map 0:v:0 -map 0:a:0 -map 0:s:0 -map_chapters -1 output.mp4

If audio and subtitles aren't in a compatible format and it's an HEVC video stream: ffmpeg -i input.mkv -c:v copy -tag:v hvc1 -c:a ac3 -b:a 640k -c:s webvtt -map 0:v:0 -map 0:a:0 -map 0:s:0 -map_chapters -1 output.mp4

holow29 commented 2 years ago

This has me thinking though, people might prefer the native video player, especially on tvOS since it feels a bit nicer.

Just wanted to say as a nobody following development here, definitely would prefer native video player on tvOS (which is my main use case for Swiftfin). It was one reason I was excited to hear about Swiftfin in the first place :) I haven't delved into any technical limitations with it, but it seems like the more native an app is on tvOS, the better experience it provides.

LePips commented 2 years ago

I'm going to leave some developer notes for others who will want to tackle this sometime

https://github.com/jellyfin/Swiftfin/discussions/324