HTML5<音频>/<视频>以及使用 FFMPEG 进行实时转码视频>音频>
因此,在我的网络服务器上,我想使用 FFMPEG 对媒体文件进行转码,以便与 HTML 或
标记一起使用。够简单吧?
当 HTTP 客户端请求转换后的文件时,转换需要实时进行。理想情况下,文件将在转码时流回 HTTP 客户端(而不是在最后转码后,因为在开始发送回任何数据之前可能需要一段时间)。
这没什么问题,只不过在当今的浏览器中,HTML5 音频或视频标记会在多个带有 Range
标头的 HTTP 请求中请求媒体文件。 有关详细信息,请参阅此问题。
在上面链接的问题中,您可以看到 Safari 请求文件的奇怪块,包括结尾的几个字节。这会带来一个问题,即 Web 服务器必须等待转换完成,才能传递文件的最终字节以符合 Range
请求。
那么我的问题是,我的思路对吗?是否有更好的方法将转码内容传递到 或
标记,而无需等待整个转换完成?提前致谢!
So from my web server, I would like to use FFMPEG to transcode a media file for use with an HTML <audio>
or <video>
tag. Easy enough right?
The conversion would need to take place in real-time, when an HTTP client requested the converted file. Ideally the file would be streamed back to the HTTP client as it is being transcoded (and not afterwards at the end, since that would potentially take a while before any data starts being sent back).
This would be fine, except that in today's browsers, an HTML5 audio or video tag requests the media file in multiple HTTP requests with the Range
header. See this question for details.
In that question linked above, you can see that Safari requests weird chunks of the file, including the ending few bytes. This poses a problem in that the web server WOULD have to wait for the conversion to finish, in order to deliver the final bytes of the file to conform to the Range
request.
So my question is, is my train of thought right? Is there a better way to deliver transcoding content to an <audio>
or <video>
tag that wouldn't involve waiting for the entire conversion to finish? Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我最近遇到了同样的问题,因为我想将我的库提供给浏览器。令人惊讶的是,通过 ffmpeg 发送流并即时交付的想法效果非常好。主要问题是支持查找...
接下来,您可以使用 Flask 在 Python 中找到代码片段来解决问题:
我们需要一个函数来流式传输内容:
然后我们需要一个函数来返回持续时间:
最后,我们破解它使用 videojs 转换为 HTML5:
可以在 https://github.com/derolf/transcoder 找到一个工作示例。
德罗
I recently run into the same issue since I want to serve my library to browsers. Surprisingly, the idea to send the stream through ffmpeg and deliver on the fly works quite well. The primary problem was to support seeking...
Following, you find code sniplets in Python using Flask to solve the problem:
We need a function to stream the content:
Then we need a function to return the duration:
And finally, we hack that into HTML5 using videojs:
A working example can be found at https://github.com/derolf/transcoder .
dero
感谢卡米洛的回复。我仔细研究了有关 Range 请求的 HTTP 规范,发现:
所以这实际上只是测试浏览器在回复
Content-Range: bytes 0-1/*
时如何反应的问题,例如。我会让你知道发生了什么。Thanks for the reply Camilo. I took a closer look at the HTTP spec regarding the Range request and found:
So it's really just a matter of testing how the browsers react when replying with a
Content-Range: bytes 0-1/*
, for example. I'll let you know what happens.我知道这是一个旧线程,但如果有人发现它并需要帮助,我无论如何都会发布它。
“user3612643”的答案是正确的,解决了寻找问题。然而,这引入了一个新问题。当前时间不再正确。要解决此问题,我们必须复制原始的 currentTime 函数。
现在,每次 video.js 调用
currentTime
(不带参数)时,它都会调用oldCurrentTime
,这是原始的currentTime
函数。其余的与“user3612643”的答案相同(谢谢!)。这适用于最新的 video.js (7.7.6)I know this is an old thread but I post it anyway if someone finds this and need help.
'user3612643' answer is correct, that fixes the seek problem. However that introduces a new problem. The current time is no longer correct. To fix this we have to copy the original
currentTime
function.Now everytime video.js calls
currentTime
(with no parameters) it will calloldCurrentTime
which is the originalcurrentTime
function. The rest is the same as 'user3612643's answer (Thanks!). This works with the newest video.js (7.7.6)AFAIK 你可以在 ffmpeg 中编码到标准输出。因此,您可以将 HTTP 服务器配置为:
我一无所知,但我认为你可以在不知道最终流长度的情况下逃脱。
顺便说一句,我认为这很容易受到 DoS 攻击。
AFAIK you can encode to stdout in ffmpeg. So you could configure your HTTP server to:
I'm clueless but I think you can get away without knowing the final stream's lenght.
On a side note, I think this is prone to DoS.
这应该可以通过 VLC 实现,我可以通过将 VLC 设置为托管大型 avi 文件来使其工作并将其转码为 OGG,然后我的 html5 引用了该流:
它能够在 vlc 中转码,并在我的 chrome 浏览器和 Android 手机上渲染得很好,但我最终采用了 不同的解决方案,而不是创建我自己的网络应用程序来托管我的媒体收藏并为请求的文件创建流 - 我看了看,但找不到已经存在的免费流,它以我需要/喜欢的方式做到了这一点。
This should be doable via VLC, I was able to get it to work by setting VLC to host a large avi file and transcode it to OGG, then my html5 referenced the stream:
It was able to transcode in vlc, and render just fine in my chrome browser and on my android phone, but I ended up taking a different solution rather than going through the work of creating my own webapp to host my media collection and create streams for requested files - I looked and couldn't find a free one already out there that did it in a way I needed/liked.