2

I'm trying to integrate live-transcoding like "plex" or "emby" with my application.

I am able to serve dash content over to shaka-player or dash.js but only in 'live-mode'. But I want to enable seeking through the player.

I looked at plex and to enable this they create their own mpd file with duration so the player will have a full seekbar.

However when seeking the player will ask for a segment number eg: 449. I need to stop ffmpeg and restart with an offset (-ss <<segment * sgement_length>>), but ffmpeg will just restart a transcode session from segment 0 with an initial segment.

What I want is to tell ffmpeg to start at a seekpoint but only output from segment number and now-on.

When playing with hls and mpegts, I can tell ffmpeg to output at a certain segment : with the option -segment_start_number but this is not available for dash. And plex use their own transcoder based of ffmpeg with the option -skip_to_segment

I tried to 'hack' around by keeping a manual offset on my web-server, even if I serve the "supposed" right segment after the seek point dash.js and shaka-player can't recover the stream.. VLC on the other habd is able to (probably more tolerent) to errors in segments.

Is the supposed right segment after a seek in dash (contains the initial segment) or only the segment.

Is ffmpeg able to start segmenting dash as a supposed segment (for seek and resume)

The same technique works in hls with forced key frames and a custom m3u8 (with all the "predicted" segments) but calculating the right segment length and the right bandwidth is much harder and hackish and dash is more tolerant to variation.

I would really like to be able to seek through my live transcoding video.

For reference here is a custom mpd file I serve to enable "seeking":

<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="urn:mpeg:dash:schema:mpd:2011"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
    profiles="urn:mpeg:dash:profile:isoff-live:2011"
    type="static"
    suggestedPresentationDelay="PT1S"
    mediaPresentationDuration="PT49M2.920S"
    maxSegmentDuration="PT2S"
    minBufferTime="PT10S">
    <Period start="PT0S" id="0" duration="PT49M2.920S">
        <AdaptationSet segmentAlignment="true">
            <SegmentTemplate timescale="1" duration="1" initialization="$RepresentationID$/initial.mp4" media="$RepresentationID$/$Number$.m4s" startNumber="1">
            </SegmentTemplate>
            <Representation id="0" mimeType="video/mp4" codecs="avc1.640029" bandwidth="3766000" width="1920" height="1080">
            </Representation>
        </AdaptationSet>
        <AdaptationSet segmentAlignment="true">
            <SegmentTemplate timescale="1" duration="1" initialization="$RepresentationID$/initial.mp4" media="$RepresentationID$/$Number$.m4s" startNumber="1">
            </SegmentTemplate>
            <Representation id="1" mimeType="audio/mp4" codecs="mp4a.40.2" bandwidth="188000" audioSamplingRate="48000">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="6"/>
            </Representation>
        </AdaptationSet>
    </Period>
</MPD>

And here is the ffmpeg command to pull it off:

ffmpeg -ss 0 -i movie.mkv -y -acodec aac -vcodec libx264 -f dash -min_seg_duration 1000000 -individual_header_trailer 0 -pix_fmt yuv420p -vf scale=trunc(min(max(iw\,ih*dar)\,1920)/2)*2:trunc(ow/dar/2)*2 -bsf:v h264_mp4toannexb -profile:v high -level 4.1 -map_chapters -1 -map_metadata -1 -preset veryfast -movflags frag_keyframe+empty_moov -use_template 1 -use_timeline 0 -remove_at_exit 1 -crf 23 -bufsize 7532k -maxrate 3766k -start_at_zero -threads 0 -force_key_frames expr:if(isnan(prev_forced_t),eq(t,t),gte(t,prev_forced_t+1)) -init_seg_name $RepresentationID$/0_initial.mp4 -media_seg_name $RepresentationID$/0_$Number$.m4s /transcoding_temp/Z1GVWEc/index.mpd

The media_seg_name is where I prepend the custom seek_point let's say I want to seek to segment 1233 the template would be:

-media_seg_name $RepresentationID$/1233_$Number$.m4s

and the segments would be 1233_1 1233_2 1233_* So I can serve the right segment after seek. but the player does not recover and still downloading subsequent segments. I guess since a new initial segment is generated and I somehow miss headers for continuous playback after seek but I'm probably wrong.

Thanks for your help

4

1 回答 1

1

您显示的清单是静态的,这意味着它不是实时服务流。如果您想让客户端通过仍在运行的实时流进行搜索,则需要定义 MPD@timeShiftBufferDepth 属性。

动态清单示例:https ://vm2.dashif.org/livesim/testpic_2s/Manifest.mpd

使用播放器:http ://reference.dashif.org/dash.js/v2.6.4/samples/dash-if-reference-player/index.html?url=https://vm2.dashif.org/livesim/ testpic_2s/Manifest.mpd

也许使用这个工作示例作为参考来确定您的实现在哪里不同?

于 2018-01-09T17:28:34.767 回答