目标:我正在尝试将VLC用作本地服务器,以展开使用Adobe AIR
,Flex
和{{创建的应用的视频功能1}}。我正在使用Actionscript
流式传输到VLC
并从我的应用中读取该输出。
VLC Streaming capabilities
VLC Flash Video
Stream VLC to Website with asf and Flash
状态:我可以启动stdout
作为后台流程,并通过其remote control interface(more 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 }} 由于某些原因?我已经尝试生成我自己的标题并在流开始之前添加它 - 我可能没有正确的标题格式。
更新2:因此,在我的Data Generation
应用中,我能够粗略地解析来自stdout
的传入AIR
流。我想知道是否正在发送FLV标头数据 - 而且它似乎是。我不知道它是否格式正确等等,但正如我上面提到的,如果我写入.flv文件而不是stdout
,则会创建一个有效的.flv文件。
现在完全不知所措 - 尝试了我能想到的一切,并跟进了我能找到的所有相关问题的网络链接。唉 - 如此接近,从VLC
开始利用stdout
会非常酷。
更新3:根据VLC
建议,我使用他/她的示例代码检查传入的字节是否有正确的数据。我得到一个巨大的字符串(1000个字符),但这些是第一个:
AIR
注意:为了让它在AIR中运行,您需要将应用配置文件定义为“extendedDesktop”
VC ONE's
答案 0 :(得分:1)
我会尝试一些事情,其中一些你可能已经考虑过了:
mpeg4
答案 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标头,全帧标记等字节)。