VLC语法转码和流到stdout?

时间:2016-10-04 18:31:50

标签: actionscript-3 flex ffmpeg vlc libvlc

目标:我正在尝试将VLC用作本地服务器,以展开使用Adobe AIRFlex和{{创建的应用的视频功能1}}。我正在使用Actionscript流式传输到VLC并从我的应用中读取该输出。

VLC Streaming capabilities
VLC Flash Video
Stream VLC to Website with asf and Flash

状态:我可以启动stdout作为后台流程,并通过其remote control interfacemore detail)对其进行控制。我可以加载,转码和流式传输本地视频文件。下面的示例应用程序是一个准系统测试平台。

问题:我正在将数据输入到我的应用中,但它不会呈现为视频。我不知道我的VLC命令是否有问题,或者是VLC的写入/读取问题。这种从AIR stdout中读取的技术可以工作(例如stdout)。

我尝试过的各种转码命令之一:

ffmpeg

这会导致数据进入我的应用,但出于某种原因,当-I rc // remote control interface -vvv // verbose debuging --sout // transcode, stream to stdout "#transcode{vcodec=FLV1}:std{access=file,mux=ffmpeg{mux=flv},dst=-}" appendBytes实例一起使用时,它不会呈现为视频。

如果我将数据写入.flv文件,则会创建一个有效的文件 - 因此损坏的部分似乎是将其写入NetStream我注意到的一件事:我没有通过stdout`方法获取元数据。如果我播放使用以下命令创建的文件,我会看到元数据。

stdout

希望有人看到我在这里出错的地方。

更新1:只是为了添加更多细节(!) - 我看了一下生成的.flv文件来检查元数据。它出现在文件的头部,如下所示。我设置了正确的// writing to a file var output:File = File.desktopDirectory.resolvePath("stream.flv"); var outputPath:String = output.nativePath; "#transcode{vcodec=FLV1}:std{access=file,mux=ffmpeg{mux=flv},dst=" + outputPath + "}"); 处理程序,如果我从磁盘播放该文件,则会看到此数据的跟踪。 onMetaData阅读并且stdout处于NetStream模式时,我看不到此跟踪。是否可能未将其发送到{{1 }} 由于某些原因?我已经尝试生成我自己的标题并在流开始之前添加它 - 我可能没有正确的标题格式。

enter image description here

更新2:因此,在我的Data Generation应用中,我能够粗略地解析来自stdout的传入AIR流。我想知道是否正在发送FLV标头数据 - 而且它似乎是。我不知道它是否格式正确等等,但正如我上面提到的,如果我写入.flv文件而不是stdout,则会创建一个有效的.flv文件。

现在完全不知所措 - 尝试了我能想到的一切,并跟进了我能找到的所有相关问题的网络链接。唉 - 如此接近,从VLC开始利用stdout会非常酷。

更新3:根据VLC建议,我使用他/她的示例代码检查传入的字节是否有正确的数据。我得到一个巨大的字符串(1000个字符),但这些是第一个:

AIR

注意:为了让它在AIR中运行,您需要将应用配置文件定义为“extendedDesktop”

VC ONE's

2 个答案:

答案 0 :(得分:1)

我会尝试一些事情,其中​​一些你可能已经考虑过了:

  1. 在没有调试的情况下尝试打开,以免弄乱你的stdout流。
  2. 如果格式特定的问题,请尝试使用其他视频格式(不是FLV)。例如,您可以尝试mpeg4
  3. 尝试将您的stdout流传输到其他内容,例如ffplay,以查看问题是流还是您接收的应用对流的假设。

答案 1 :(得分:1)

在你的其他问题的评论中,你问我的想法:

我在您的代码中注意到您在OSX环境下运行VLC流程。
在Windows PC上,请注意-I rc以后不会响应发送的standardInput命令。我是Windows用户,因此无法帮助您完成该部分。

使用--no-rc-fake-tty甚至--rc-fake-tty尝试,VLC仍然没有回复PC上的stdout

你想要播放&在VLC中搜索但是在AS3中观看结果(如投影屏幕),对吧?但是我甚至不确定VLC会从你选择的时间戳等开始给你回FLV标签(通过寻找你正在访问特定时间戳的FLV标签和相关的a / v数据)...

其他FFmpeg / Mencoder供电的玩家,比如MPlayer我测试过的只发回"状态"播放期间将文本数据转换为stdout(因此无法将其提供给NetStream解码器进行显示。)

  

我能够粗略地解析来自的传入stdout流   VLC。我想看看FLV标题数据是否正在发送 - 以及它   似乎是。我不知道它的格式是否正确等等。

检查字节:(有效的FLV标题以46 4C 56 01 05 00 00 00 09 00 00 00 00开头)

只需使用" bytes check"的复制粘贴更新您的问题。以下功能的结果。然后更容易告诉你它是否可玩或者你需要一些替代方案。

1)设置一些公共(或私人)变量......

  • 制作public var temp_String : String = "";
  • 制作public var videoStream:ByteArray = new ByteArray();

2)用以下代码替换你的函数onOutputData ......

public function onOutputData(event:ProgressEvent):void 
{ 
    if (process && process.running)
    {
        if (process.standardOutput.bytesAvailable)
        {
            //# make a private/public bytearray outside of this function 
            //var videoStream:ByteArray = new ByteArray();

            process.standardOutput.readBytes(videoStream, videoStream.length, process.standardOutput.bytesAvailable);

            dataIn = process.standardOutput.bytesAvailable; 
            dataTotal += dataIn;
            //report.text = String("Current Bytes: " + dataIn + "\t Total Bytes: "+ dataTotal);

            if (videoStream.length >= 1000 )
            {
                //ns.appendBytes(videoStream);

                temp_String = bytes_toString(videoStream);
                trace("bytes checking : " + "\n");
                trace( temp_String ); //see hex of FLV bytes

                //# temporary pausing of progress events 
                process.removeEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
            }
            //trace(ns.info);
        }
    }
}

支持函数bytes_toString代码:

public function bytes_toString ( ba:ByteArray ) : String
{
    var str_Hex:String = "";    var len:uint = ba.length;

    ba.position = 0;

    for (var i:uint = 0; i < len; i++) 
    {
        var n:String=ba.readUnsignedByte().toString(16); 

        if(n.length<2) //padding
        { n="0"+n; }    str_Hex += n ;
    }

    return str_Hex.toUpperCase();
}

其他一些说明:

每次触发进度事件一次只能捕获32kb / 64kb的传入stdout字节数据包。

您在progressEvent之外创建videoStream:ByteArray = new ByteArray();,以便每个事件触发都不会生成新的byteArray(丢弃以后完整FLV标记可能需要的旧数据)。

不要将每个数据包写入0位置,因为这会覆盖现有数据。使用videoStream.length作为新的写作位置添加到现有的结尾。

process.standardOutput.readBytes(videoStream, videoStream.length, process.standardOutput.bytesAvailable);

同样if (videoStream.length){ ns.appendBytes(videoStream); }有点危险。如果你过早追加,任何不完整的数据(标题,帧或其他)都会堵塞NetStream解码器。它不会重新启动,除非您重置所有内容并重新开始(重新附加完整FLV标头,全帧标记等字节)。