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

Force Transcoding LiveTV #2160

Merged
merged 45 commits into from
Feb 25, 2020
Merged

Force Transcoding LiveTV #2160

merged 45 commits into from
Feb 25, 2020

Conversation

Artiume
Copy link
Contributor

@Artiume Artiume commented Dec 16, 2019

Changes

Server side PR to enable Force Transcoding for Remote Streams. This should fix several issues. On Android clients, I am currently unable to stream livetv since the backend doesn't fallback to transcode on Direct Play failure. This is also an attempt to increase play-ability for clients that don't correctly report their compatibility. See attached issue for source.

Web Side PR jellyfin/jellyfin-web#636

Issues

#1202

@dkanada
Copy link
Member

dkanada commented Dec 18, 2019

I have a few reservations about this change.

  1. We don't want users to have any control over whether or not the server is transcoding their content, because it's very resource intensive.
  2. What about music, movies, and other media types? I'm not sure a unique setting for every type is the best idea.

I would much rather have some kind of method within the player (above the Auto setting) to request Source or Direct playback, which would be format agnostic.

@Artiume
Copy link
Contributor Author

Artiume commented Dec 18, 2019

So this pulls the RemoteMedia trigger so it only impacts external feeds such as live tv. The setting itself is set on the admin page, not by the user.

With further testing, it's revealing behind the scenes transcoding issues such as those with clients reporting their wrong compatibility.

https://domain.tld/videos/484748/stream.mkv?DeviceId=60de5944644&MediaSourceId=2be21c256186166a407edf0be4db&VideoCodec=h264,vp8,vp9&AudioCodec=mp3,aac,opus,flac,vorbis&AudioStreamIndex=-1&VideoBitrate=8000000&AudioBitrate=135750&PlaySessionId=651618521bd28969b1dbb6f3f5bb5&api_key=e80&LiveStreamId=a17c76809efa0d56b934a82adec00a87b837fb0_2be21c236a407edf0be4db&TranscodingMaxAudioChannels=2&CopyTimestamps=true&RequireAvc=false&h264-profile=high,main,baseline,constrainedbaseline&h264-level=41&TranscodeReasons=ContainerBitrateExceedsLimit&allowVideoStreamCopy=false&allowAudioStreamCopy=false {"Protocol":"Http","Id":"2be21c256186162a936a407edf0be4db","Path":"http://remotepath","Type":"Default","Container":"mpegts","IsRemote":true,"ReadAtNativeFramerate":false,"IgnoreDts":true,"IgnoreIndex":false,"GenPtsInput":false,"SupportsTranscoding":true,"SupportsDirectStream":false,"SupportsDirectPlay":false,"IsInfiniteStream":true,"RequiresOpening":true,"RequiresClosing":true,"LiveStreamId":"a17c75760a04e99b68cf766e11316e1c_09ef87b837fb0_2be21c256186162a936a407edf0be4db","RequiresLooping":true,"SupportsProbing":true,"MediaStreams":[{"Codec":"h264","TimeBase":"1/90000","CodecTimeBase":"1001/120000","VideoRange":"SDR","DisplayTitle":"720P H264","NalLengthSize":"0","IsInterlaced":false,"BitRate":8000000,"BitDepth":8,"RefFrames":1,"IsDefault":false,"IsForced":false,"Height":720,"Width":1280,"AverageFrameRate":59.94006,"RealFrameRate":59.94006,"Profile":"High","Type":"Video","AspectRatio":"16:9","Index":-1,"IsExternal":false,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"PixelFormat":"yuv420p","Level":41,"IsAnamorphic":false},{"Codec":"aac","TimeBase":"1/90000","CodecTimeBase":"1/48000","DisplayTitle":"AAC stereo","IsInterlaced":false,"ChannelLayout":"stereo","BitRate":135750,"Channels":2,"SampleRate":48000,"IsDefault":false,"IsForced":false,"Profile":"LC","Type":"Audio","Index":-1,"IsExternal":false,"IsTextSubtitleStream":false,"SupportsExternalStream":false,"Level":0}],"Formats":[],"Bitrate":8135750,"RequiredHttpHeaders":{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"},"AnalyzeDurationMs":3000} /usr/local/bin/ffmpeg -analyzeduration 3000000 -user_agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" -fflags +igndts -f mpegts -stream_loop -1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 2 -i "http:// remote path " -sn -codec:v:0 libx264 -force_key_frames "expr:gte(t,n_forced*5)" -vf "scale=trunc(min(max(iw\,ih*dar)\,1920)/2)*2:trunc(ow/dar/2)*2" -pix_fmt yuv420p -preset superfast -crf 23 -maxrate 8000000 -bufsize 16000000 -profile:v high -level 4.1 -x264opts:0 subme=0:me_range=4:rc_lookahead=10:me=dia:no_chroma_me:8x8dct=0:partitions=none -flags -global_header -vsync cfr -map_metadata -1 -map_chapters -1 -threads 0 -codec:a:0 libmp3lame -ac 2 -ab 135750 -y "/ram_transcode/506947d873e5a7b3d852f43903babe14.mkv" ffmpeg version 4.2.1 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 7 (Ubuntu 7.4.0-1ubuntu1~18.04.1) configuration: --disable-debug --disable-doc --disable-ffplay --enable-vaapi --enable-shared --enable-avresample --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-gnutls --enable-gpl --enable-libass --enable-libfreetype --enable-libvidstab --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx265 --enable-libxvid --enable-libx264 --enable-libkvazaar --enable-libaom --extra-libs=-lpthread --enable-postproc --enable-cuvid --enable-nvenc --enable-version3 --enable-rpath --extra-cflags=-I/opt/ffmpeg/include --extra-ldflags=-L/opt/ffmpeg/lib --extra-libs=-ldl --prefix=/opt/ffmpeg libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100 Input #0, mpegts, from 'http:// remote path': Duration: N/A, start: 4160.402933, bitrate: N/A Program 1 Metadata: service_name : Service01 service_provider: FFmpeg Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], Closed Captions, 59.94 fps, 59.94 tbr, 90k tbn, 119.88 tbc Stream #0:1[0x101]: Audio: aac (LC) ([15][0][0][0] / 0x000F), 48000 Hz, stereo, fltp, 126 kb/s Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264)) Stream #0:1 -> #0:1 (aac (native) -> mp3 (libmp3lame)) Press [q] to stop, [?] for help [libx264 @ 0x563d65222f40] using SAR=1/1 [libx264 @ 0x563d65222f40] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 [libx264 @ 0x563d65222f40] profile Main, level 4.1 Could not write header for output file #0 (incorrect codec parameters ?): Invalid data found when processing input Error initializing output stream 0:0 -- [libmp3lame @ 0x563d652224c0] 3 frames left in the queue on closing Conversion failed!

This is an attempt to stream on Android. If I use a browser and watch a stream, I have success so it's limited to the android app, I haven't tested my android TV but I imagine that it will have the same issue.

I would like to fix the client compatibility but I'm not sure where it's located in the coding yet.

@Artiume
Copy link
Contributor Author

Artiume commented Dec 20, 2019

Doing some more testing, when this is turned on, video, audio and container all say not compatible and all 3 will be transcoded. I think that remuxing the container from mpegts to hls alone would solve the issue, no need to transcode the video/audio. I noticed this when I started to have a few channels that would suddenly have poor performance.

Reason for transcoding: ContainerNotSupported VideoCodecNotSupported AudioCodecNotSupported

MediaBrowser.Api/Playback/MediaInfoService.cs Outdated Show resolved Hide resolved
MediaBrowser.Api/Playback/MediaInfoService.cs Outdated Show resolved Hide resolved
MediaBrowser.Api/Playback/MediaInfoService.cs Outdated Show resolved Hide resolved
MediaBrowser.Api/Playback/MediaInfoService.cs Outdated Show resolved Hide resolved
@JustAMan
Copy link
Contributor

All in all, this looks a bit overcomplicated for "forcing" a flag. I should probably read it once more...

@Artiume
Copy link
Contributor Author

Artiume commented Jan 10, 2020

I welcome any improvements :). Transcoding instead of DirectStream might be required unless you know a better method of handling this issue:

for avoiding playback stuttering in some cases with "DirectStream" - ffmpeg messages like "[segment @ 0x5645aece2c00] Non-monotonous DTS in output stream 0:0; previous: 272204, current: 268604; changing to 272205. This may result in incorrect timestamps in the output file."

@Artiume
Copy link
Contributor Author

Artiume commented Feb 6, 2020

@cvium @JustAMan

Removed forceDirectPlayRemoteMediaSource in a few places to clean up the code, but I didn't want to remove it completely without making sure it wouldnt have an impact elsewhere.

Allowed for Audio to be copied instead of forced.

Fixed Max Bitrate.

@Artiume
Copy link
Contributor Author

Artiume commented Feb 7, 2020

#2273

The remuxing issue is creeping up here since livetv can't get right when it comes to Anamorphic Containers. I think that's why audio was transcoding as well, haha. I'm gonna look to see if I can find where FFmpeg is told to use SAR instead of DAR.

@Artiume
Copy link
Contributor Author

Artiume commented Feb 9, 2020

@thornbill added you since you'd be good to see its performance on Android TV. @nielsvanvelzen and I have confirmed a live tv issue in 0.11.1 by using the forced transcoding policy enabled in this PR.

@dkanada dkanada added this to In progress in Release 10.5.0 via automation Feb 12, 2020
@Artiume Artiume requested a review from cvium February 19, 2020 11:33
Copy link
Member

@cvium cvium left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's break stuff

Copy link
Contributor

@JustAMan JustAMan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still feels like a hack instead of a solution (I still think it's a problem of somehow broken source which we should detect and re-encode if it's broken without requiring user to tick something manually), but better do this for now than have this broken I think.

@JustAMan JustAMan merged commit a075fef into jellyfin:master Feb 25, 2020
Release 10.5.0 automation moved this from In progress to Done Feb 25, 2020
@dragon2611
Copy link

@Artiume Seemed to work, with both the SD and HD channel, I tested to a 3rd gen chromecast.

If this is stable then it saves me running a 2nd TvH instance (the wetek play doesn't have enough grunt to transcode)

@Artiume
Copy link
Contributor Author

Artiume commented Mar 10, 2020

Awesome. I've had reports of audio being out of sync or messed up on fire stick, let me know if you notice anything like that. My first revision forced transcode the audio as well.

@dragon2611
Copy link

So far all i've noticed is ffmpeg is still taking a lot of CPU after I turned off power to the chromecast, I'm not sure if the JF server noticed it's gone yet.

@Artiume
Copy link
Contributor Author

Artiume commented Mar 10, 2020

If you set max streams available, you should be able to see something in the logs about reducing consumer count when the server releases the stream.

@dragon2611
Copy link

It did eventually release it, Jellyfin interface is rather slow to respond but I think it's the Iowait on the terrible HDD in the machine it's running on (Mac Mini I had spare, running proxmox), really should get around to taking it to bits and putting an SSD in.

@Artiume
Copy link
Contributor Author

Artiume commented Mar 10, 2020

Makes sense, glad you've found it useful :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

7 participants