Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Video HTML5<;音频>/&书信电报;视频>;使用FFMPEG进行实时转码_Video_Audio_Html_Ffmpeg_Transcoding - Fatal编程技术网

Video HTML5<;音频>/&书信电报;视频>;使用FFMPEG进行实时转码

Video HTML5<;音频>/&书信电报;视频>;使用FFMPEG进行实时转码,video,audio,html,ffmpeg,transcoding,Video,Audio,Html,Ffmpeg,Transcoding,因此,在我的web服务器上,我想使用FFMPEG对媒体文件进行转码,以便与HTML一起使用 在上面链接的问题中,您可以看到Safari请求文件的奇怪块,包括结尾的几个字节。这造成了一个问题,web服务器必须等待转换完成,以便交付文件的最终字节以符合范围请求 所以我的问题是,我的思路对吗?有没有更好的方法将转码内容传递到不需要等待整个转换完成的或标记?提前谢谢 AFAIK您可以在ffmpeg中编码到标准输出。因此,您可以将HTTP服务器配置为: 接收时开始编码以缓存 将请求的字节范围流到客户端

因此,在我的web服务器上,我想使用FFMPEG对媒体文件进行转码,以便与HTML
一起使用

在上面链接的问题中,您可以看到Safari请求文件的奇怪块,包括结尾的几个字节。这造成了一个问题,web服务器必须等待转换完成,以便交付文件的最终字节以符合
范围
请求


所以我的问题是,我的思路对吗?有没有更好的方法将转码内容传递到不需要等待整个转换完成的
标记?提前谢谢

AFAIK您可以在ffmpeg中编码到标准输出。因此,您可以将HTTP服务器配置为:

  • 接收时开始编码以缓存
  • 将请求的字节范围流到客户端
  • 填充缓冲区并将其用于后续范围
我不知道,但我认为你可以在不知道最后一条河的长度的情况下逃走


另一方面,我认为这很容易被拒绝。

谢谢你的回复Camilo。我仔细查看了有关范围请求的HTTP规范,发现:

The header SHOULD indicate the total length of the full entity-body, unless
this length is unknown or difficult to determine. The asterisk "*" character
means that the instance-length is unknown at the time when the response was
generated.
因此,这实际上只是测试浏览器在使用
内容范围(例如字节0-1/*
)进行回复时的反应。我会让你知道会发生什么。

这应该可以通过,我可以通过设置VLC来承载一个大的avi文件并将其转换为OGG来实现,然后我的html5引用了这个流:

<source src="http://localhost:8081/stream.ogg">


它能够在vlc中进行代码转换,在我的chrome浏览器和android手机上呈现得很好,但是,我最终选择了一个网络应用程序,而不是创建我自己的网络应用程序来承载我的媒体收藏,并为请求的文件创建流。我查看了一下,却找不到一个免费的应用程序,它以我需要/喜欢的方式实现了这一点。

我最近遇到了同样的问题,因为我想为浏览器提供我的库。令人惊讶的是,通过ffmpeg发送流并实时交付的想法非常有效。主要问题是支持寻求

下面,您可以在Python中找到使用Flask解决问题的代码片段:

我们需要一个函数来流式传输内容:

@app.route('/media/<path:path>.ogv')
def media_content_ogv(path):
    d= os.path.abspath( os.path.join( config.media_folder, path ) )
    if not os.path.isfile( d ): abort(404)
    start= request.args.get("start") or 0
    def generate():
        cmdline= list()
        cmdline.append( config.ffmpeg )
        cmdline.append( "-i" )
        cmdline.append( d );
        cmdline.append( "-ss" )
        cmdline.append( str(start) );
        cmdline.extend( config.ffmpeg_args )
        print cmdline
        FNULL = open(os.devnull, 'w')
        proc= subprocess.Popen( cmdline, stdout=subprocess.PIPE, stderr=FNULL )
        try:
            f= proc.stdout
            byte = f.read(512)
            while byte:
                yield byte
                byte = f.read(512)
        finally:
            proc.kill()

    return Response(response=generate(),status=200,mimetype='video/ogg',headers={'Access-Control-Allow-Origin': '*', "Content-Type":"video/ogg","Content-Disposition":"inline","Content-Transfer-Enconding":"binary"})
@app.route('/media/.ogv'))
def媒体内容ogv(路径):
d=os.path.abspath(os.path.join(config.media_文件夹,path))
如果不是os.path.isfile(d):中止(404)
start=request.args.get(“start”)或0
def generate():
cmdline=list()
cmdline.append(config.ffmpeg)
cmdline.append(“-i”)
cmdline.append(d);
cmdline.append(“-ss”)
cmdline.append(str(start));
cmdline.extend(config.ffmpeg_参数)
打印命令行
FNULL=open(os.devnull,'w')
proc=subprocess.Popen(cmdline,stdout=subprocess.PIPE,stderr=FNULL)
尝试:
f=程序标准输出
字节=f.read(512)
而字节:
屈服字节
字节=f.read(512)
最后:
程序kill()
返回响应(Response=generate(),status=200,mimetype='video/ogg',headers={'Access-Control-Allow-Origin':'*',“内容类型”:“video/ogg”,“内容处置”:“inline”,“内容传输编码”:“binary”})
然后我们需要一个函数来返回持续时间:

@app.route('/media/<path:path>.js')
def media_content_js(path):
    d= os.path.abspath( os.path.join( config.media_folder, path ) )
    if not os.path.isfile( d ): abort(404)
    cmdline= list()
    cmdline.append( config.ffmpeg )
    cmdline.append( "-i" )
    cmdline.append( d );
    duration= -1
    FNULL = open(os.devnull, 'w')
    proc= subprocess.Popen( cmdline, stderr=subprocess.PIPE, stdout=FNULL )
    try:
        for line in iter(proc.stderr.readline,''):
            line= line.rstrip()
            #Duration: 00:00:45.13, start: 0.000000, bitrate: 302 kb/s
            m = re.search('Duration: (..):(..):(..)\...', line)
            if m is not None: duration= int(m.group(1)) * 3600 + int(m.group(2)) * 60 + int(m.group(3)) + 1
    finally:
        proc.kill()

    return jsonify(duration=duration)
@app.route('/media/.js')
def媒体内容(路径):
d=os.path.abspath(os.path.join(config.media_文件夹,path))
如果不是os.path.isfile(d):中止(404)
cmdline=list()
cmdline.append(config.ffmpeg)
cmdline.append(“-i”)
cmdline.append(d);
持续时间=-1
FNULL=open(os.devnull,'w')
proc=subprocess.Popen(cmdline,stderr=subprocess.PIPE,stdout=FNULL)
尝试:
对于国际热核实验堆(iter)中的管线(程序标准读入管线“”):
line=line.rstrip()
#持续时间:00:00:45.13,开始时间:0.000000,比特率:302 kb/s
m=重新搜索((..):(..):(..)\…,第行)
如果m不是None:duration=int(m.group(1))*3600+int(m.group(2))*60+int(m.group(3))+1
最后:
程序kill()
返回jsonify(持续时间=持续时间)
最后,我们使用videojs将其植入HTML5:

<!DOCTYPE html>
<html>
<head>
    <link href="//vjs.zencdn.net/4.5/video-js.css" rel="stylesheet">
    <script src="//vjs.zencdn.net/4.5/video.js"></script>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</head>
<body>
    <video id="video" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264">
    </video>
    <script>
        var video= videojs('video');
        video.src("media/testavi.avi.ogv");

        // hack duration
        video.duration= function() { return video.theDuration; };
        video.start= 0;
        video.oldCurrentTime= video.currentTime;
        video.currentTime= function(time) 
        { 
            if( time == undefined )
            {
                return video.oldCurrentTime() + video.start;
            }
            console.log(time)
            video.start= time;
            video.oldCurrentTime(0);
            video.src("media/testavi.avi.ogv?start=" + time);
            video.play();
            return this;
        };

        $.getJSON( "media/testavi.avi.js", function( data ) 
        {
            video.theDuration= data.duration;
        });
    </script>
</body>

var video=videojs(“视频”);
video.src(“media/testavi.avi.ogv”);
//黑客攻击持续时间
video.duration=function(){return video.theDuration;};
video.start=0;
video.oldCurrentTime=video.currentTime;
video.currentTime=函数(时间)
{ 
如果(时间==未定义)
{
返回video.oldCurrentTime()+video.start;
}
console.log(时间)
视频。开始=时间;
视频。oldCurrentTime(0);
video.src(“media/testavi.avi.ogv?start=“+time”);
video.play();
归还这个;
};
$.getJSON(“media/testavi.avi.js”,函数(数据)
{
video.theDuration=data.duration;
});
有关工作示例,请访问


dero

我知道这是一个旧线程,但如果有人发现它并需要帮助,我还是会发布它

“user3612643”的答案是正确的,这修复了seek问题。然而,这带来了一个新问题。当前时间不再正确。要解决此问题,我们必须复制原始的
currentTime
函数

现在,每当video.js调用
currentTime
(无参数)时,它都会调用
oldCurrentTime
,这是原始的
currentTime
函数。其余部分与“user3612643”的答案相同(谢谢!)。这适用于最新的video.js(7.7.6)

video=videojs(“视频”);
video.src({
src:'http://localhost:4000/api/video/sdf',
键入:“视频/webm”
});
//黑客攻击持续时间
video.duration=function(){return vide