是否可以预生成m3u8文件? (仅限播放列表)并跳过转码?

问题描述 投票:0回答:1

我正在尝试创建一个媒体服务器,并且只想在播放视频时对其进行转码。但是我需要提前播放列表,以便客户端播放可以加载视频元数据。这可能吗?

我想做这样的事情:

Client -> GET m3u8 (pregenerated in advance)
Client -> GET ts -> Transcode only this single ts file
Client -> GET ts -> Transcode only this single ts file
Client -> GET ts -> Transcode only this single ts file

我不想立即对整个视频进行转码,我希望能够仅对请求的部分进行转码。

这可能吗?如果需要,也可以使用 MPEG-DASH。

ffmpeg http-live-streaming mpeg-dash hls.js
1个回答
0
投票

我的解决方案是根据视频总时长自行生成m3u8并首先提供服务。

当运行时 ffmpeg 运行时,使用请求的段号生成开始秒并将其放在 ffmpeg 命令选项的“-ss”之后,并且您必须指定“-r”选项以匹配最终 ts 段的 hls_time 和 fps时间与您预定义的片段持续时间相匹配。否则您将得到以下错误的 ts 持续时间

root@YOLE-UJIK:~/tran_6# cat generated_by_ffmpeg.m3u8 
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:5
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:5.005000,
stream0_0.ts
#EXTINF:5.005000,
stream0_1.ts
#EXTINF:5.005000,
stream0_2.ts
#EXTINF:5.005000,
stream0_3.ts
#EXTINF:5.005000,
stream0_4.ts
#EXTINF:5.005000,
stream0_5.ts
#EXTINF:4.971633,
stream0_6.ts
#EXTINF:5.005000,
stream0_7.ts


例如

我使用 golang 作为 hls 服务代码语言,我的分段持续时间预定义为 5 秒

我使用视频总持续时间和片段持续时间选项生成 m3u8 部分,下面的代码显示了如何编写保留 m3u8:

func BuildMainPlaylistTranscoding(opt Sw, segmentDuration float64) string {

    segmentDurationsSeconds := []float64{}
    totalDuration := float64(opt.Duration)
    standardPartSegDuration := segmentDuration
    for ; totalDuration > 0; totalDuration -= standardPartSegDuration {
        if totalDuration > standardPartSegDuration {
            segmentDurationsSeconds = append(segmentDurationsSeconds, standardPartSegDuration)
        } else {
            segmentDurationsSeconds = append(segmentDurationsSeconds, totalDuration)
        }
    }

    buildder := strings.Builder{}
    buildder.WriteString(fmt.Sprintf(`#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:%d
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD`, 6))
    // apple must end with .ts, otherwise safari will not request ts data
    for index := 0; index < len(segmentDurationsSeconds); index++ {
        buildder.WriteString(fmt.Sprintf("\n#EXTINF:%.3f,\nstream0_%d.ts", segmentDurationsSeconds[index], index))
    }
    buildder.WriteString(fmt.Sprintf("\n#EXT-X-ENDLIST"))
    return buildder.String()
}

当媒体段http请求到达时,我使用下面的ffmpeg命令来生成ts段并提供服务。

ffmpeg -hide_banner -analyzeduration 200M -init_hw_device vaapi=va:/dev/dri/renderD128 -filter_hw_device va -hwaccel vaapi -hwaccel_output_format vaapi -i "/data/user/admin/Downloads/迪迦奥特曼 EP48 -月球来的逃亡者1080P.mkv" -copyts -autoscale 0 -map_metadata -1 -map_chapters -1 -threads 0 -codec:v:0 h264_vaapi -b:v 1000000 -r 30 -force_key_frames "expr:gte(t,n_forced*5)" -filter_complex "[0:3]scale=s=960x720:flags=fast_bilinear[sub];[0:0]setparams=color_primaries=bt709:color_trc=bt709:colorspace=bt709,scale_vaapi=w=960:h=720:format=nv12:extra_hw_frames=24,hwdownload,format=nv12[main];[main][sub]overlay=eof_action=pass:shortest=1:repeatlast=0,hwupload_vaapi" -start_at_zero -codec:a:0 aac -ac 2 -ab 128000 -max_muxing_queue_size 2048 -f hls -start_number 0 -hls_time 5 -hls_segment_type mpegts -hls_list_size 0 -hls_segment_filename "/root/tran_7/stream0_%d.ts" -hls_playlist_type vod "/root/tran_7/generated_by_ffmpeg.m3u8"

© www.soinside.com 2019 - 2024. All rights reserved.