我用ffmpeg从yuv帧创建了hls流,效果似乎很好。它会创建一个播放列表,并按预期更新该播放列表以及所有.ts文件。但是,即使videojs也拒绝播放它,而且我真的没什么主意,可能会错过显而易见的内容?
首先,不断更新的m3u8列表:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:190
#EXTINF:2.000000,
test190.ts
#EXTINF:2.000000,
test191.ts
#EXTINF:2.000000,
test192.ts
#EXTINF:2.000000,
test193.ts
#EXTINF:2.000000,
test194.ts
这些.ts文件存在,并且大小约为250 KB。 然后,我打开此标准videojs html文件(位于同一目录中):
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>videojs-contrib-hls embed</title>
<link href="video-js.css" rel="stylesheet">
</head>
<body>
<h1>VSTream</h1>
<video-js id="my_video_1" class="vjs-default-skin" controls preload="auto" width="640" height="268">
<source src="test.m3u8" type="application/x-mpegURL">
</video-js>
<script src="video.min.js"></script>
<script src="videojs-http-streaming.min.js"></script>
<script>
var player = videojs('my_video_1');
</script>
</body>
</html>
我在Firefox(或Chrome或Edge,均无法使用)中打开它,并使用其调试器,该调试器在控制台中显示:
VIDEOJS:警告:已经存在一个名为“ reloadSourceOnError”的插件。 您可能要避免重新注册插件! video.min.js:12:977 不是“ application / x-mpegURL”的指定“类型”属性 支持的。加载媒体资源test.m3u8失败。 vstream.html全部 候选资源加载失败。媒体加载已暂停。 vstream.html XML分析错误:语法错误位置:file:/// C:/test/test.m3u8 行号1,列1:2 test.m3u8:1:1 MouseEvent.mozPressure是 不推荐使用。请改用PointerEvent.pressure。 video.min.js:12:9031 VIDEOJS:错误:(CODE:3 MEDIA_ERR_DECODE)播放无法继续。没有 可用的工作或支持的播放列表。对象{代码:3,消息: “无法继续播放。无法使用或支持 播放列表。”} video.min.js:12:977
这对我来说没有多大意义。为什么它会为m3u8文件引发XML解析错误?当然,MEDIA_ERR_DECODE指向某个方向,但是fMP4文件仍然存在相同的问题。
相关的ffmpeg c ++代码(格式为“ hls”,formatContext在其他情况下效果很好,gop为2):
AVDictionary* options = 0;
if (fragmented)
{
// type
if (codecID == AV_CODEC_ID_H264)
av_dict_set (&options, "hls_segment_type", "fmp4", 0);
else
av_dict_set (&options, "hls_segment_type", "mpegts", 0);
av_dict_set (&options, "hls_time", "2.0", 0);
av_dict_set_int (&options, "hls_list_size", 5, 0);
av_dict_set (&options, "hls_flags", "delete_segments", 0);
}
int ret = avformat_write_header (formatContext, &options);
...返回成功。然后写框架
int ret = avcodec_send_frame (videoStream->codecContext, frame);
av_init_packet (avPacket);
AVRational timeBase = videoStream->getTimeBase ();
avPacket->stream_index = streams.indexOf (videoStream);
ret = avcodec_receive_packet (videoStream->codecContext, avPacket);
avPacket->duration = av_rescale_q (1, videoStream->codecContext->time_base, videoStream->getTimeBase ());
pts += avPacket->duration;
avPacket->pts = pts;
avPacket->dts = pts; // AV_NOPTS_VALUE;
ret = av_interleaved_write_frame (formatContext, avPacket);
(此处的videoStream是表示avstream的内部对象)。 为了清楚起见,我省略了错误检查。所有返回值均显示成功。 感谢您的帮助!