使用 ffmpeg 进行自适应压缩
adaptive compression with ffmpeg
我目前正在开发一个应用程序,它可以在浏览器中(在 HTML5 视频元素中)显示来自不同来源(主要是 IP 摄像机)的图像。 UI 将允许矩阵视图,因此通常会同时显示 16 个或更多摄像机。
从相机我得到 MJPEG 流或 JPEG 图像(我 "convert" 到 MJPEG 流)。因此,对于相机,我有一个 MJPEG 流,我将其设置为 ffmpeg 的输入。我指示 ffmpeg 将其转换为 MP4 和 H.264,并将输出公开为 tcp 流,如下所示:
ffmpeg -f mjpeg -i "http://localhost/video.mjpg" -f mp4 -vcodec libx264 "tcp://127.0.0.1:5001?listen"
这在本地主机上工作得很好,我在网页上以最佳质量显示流。
但这必须在各种网络条件下工作。我尝试了 chrome 节流设置,并注意到如果网络速度略低于所需速度(由我在 ffmpeg 中使用的当前压缩设置给出),事情就会开始出错:来自流开始延迟(因此,不再是实时流),直至 'live' 图像在浏览器中完全冻结。
我需要的是 "adaptive" 与当前网络速度相关的压缩方法。
我的问题是:
ffmpeg是否能够处理这个问题,以适应网络条件——速度低时自动降低压缩质量;所以浏览器中的图像质量会较低,但会实时显示(这对我来说最重要)
如果没有,有没有办法解决这个问题?
有没有办法检测网络瓶颈? (然后用较低的压缩参数重启ffmpeg;这不是动态自适应流,但聊胜于无)
提前致谢!
您的解决方案不适用于本地网络。为什么?因为你必须使用 HTTP。为此,最好的解决方案是使用 HLS 或 DASH。
HLS
ffmpeg -i input.mp4 -s 640x360 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls index.m3u8
要生成自适应流,您必须创建二级索引。我这里就不解释了,因为苹果的文档写的很清楚:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008332-CH1-SW1
在标准中:https://datatracker.ietf.org/doc/html/draft-pantos-http-live-streaming-18
DASH
目前 FFMPEG 不支持 Dash 编码。您可以使用 FFMPEG ( [https://www.ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment][1] ) 进行分段,但我建议结合使用 FFMPEG 和 MP4Box。 FFMPEG 用于转码您的实时视频,MP4Box 用于分段和创建索引 .mpd。
MP4Box 是 GPAC 的一部分 ( [http://gpac.wp.mines-telecom.fr/][2] )
一个例子可以是(使用 h264)- 如果你需要 vp8(webm,使用 -vcodec libvpx 和 -f webm 或 -f ts):
ffmpeg -threads 4 -f v4l2 -i /dev/video0 -acodec libfaac -ar 44100 -ab 128k -ac 2 -vcodec libx264 -r 30 -s 1280x720 -f mp4 -y "$movie" > temp1.mp4 && MP4Box -dash 10000 -frag 1000 -rap "$movie"
我目前正在开发一个应用程序,它可以在浏览器中(在 HTML5 视频元素中)显示来自不同来源(主要是 IP 摄像机)的图像。 UI 将允许矩阵视图,因此通常会同时显示 16 个或更多摄像机。 从相机我得到 MJPEG 流或 JPEG 图像(我 "convert" 到 MJPEG 流)。因此,对于相机,我有一个 MJPEG 流,我将其设置为 ffmpeg 的输入。我指示 ffmpeg 将其转换为 MP4 和 H.264,并将输出公开为 tcp 流,如下所示:
ffmpeg -f mjpeg -i "http://localhost/video.mjpg" -f mp4 -vcodec libx264 "tcp://127.0.0.1:5001?listen"
这在本地主机上工作得很好,我在网页上以最佳质量显示流。
但这必须在各种网络条件下工作。我尝试了 chrome 节流设置,并注意到如果网络速度略低于所需速度(由我在 ffmpeg 中使用的当前压缩设置给出),事情就会开始出错:来自流开始延迟(因此,不再是实时流),直至 'live' 图像在浏览器中完全冻结。
我需要的是 "adaptive" 与当前网络速度相关的压缩方法。
我的问题是:
ffmpeg是否能够处理这个问题,以适应网络条件——速度低时自动降低压缩质量;所以浏览器中的图像质量会较低,但会实时显示(这对我来说最重要)
如果没有,有没有办法解决这个问题?
有没有办法检测网络瓶颈? (然后用较低的压缩参数重启ffmpeg;这不是动态自适应流,但聊胜于无)
提前致谢!
您的解决方案不适用于本地网络。为什么?因为你必须使用 HTTP。为此,最好的解决方案是使用 HLS 或 DASH。
HLS
ffmpeg -i input.mp4 -s 640x360 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls index.m3u8
要生成自适应流,您必须创建二级索引。我这里就不解释了,因为苹果的文档写的很清楚:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008332-CH1-SW1
在标准中:https://datatracker.ietf.org/doc/html/draft-pantos-http-live-streaming-18
DASH
目前 FFMPEG 不支持 Dash 编码。您可以使用 FFMPEG ( [https://www.ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment][1] ) 进行分段,但我建议结合使用 FFMPEG 和 MP4Box。 FFMPEG 用于转码您的实时视频,MP4Box 用于分段和创建索引 .mpd。
MP4Box 是 GPAC 的一部分 ( [http://gpac.wp.mines-telecom.fr/][2] )
一个例子可以是(使用 h264)- 如果你需要 vp8(webm,使用 -vcodec libvpx 和 -f webm 或 -f ts):
ffmpeg -threads 4 -f v4l2 -i /dev/video0 -acodec libfaac -ar 44100 -ab 128k -ac 2 -vcodec libx264 -r 30 -s 1280x720 -f mp4 -y "$movie" > temp1.mp4 && MP4Box -dash 10000 -frag 1000 -rap "$movie"