gpt4 book ai didi

actionscript-3 - AS3 NetStream AppendBytes寻求问题

转载 作者:行者123 更新时间:2023-12-04 21:38:32 25 4
gpt4 key购买 nike

我在AS3中遇到NetStream的问题。我正在从事的项目允许用户浏览视频(本地)并播放。我遇到的问题是,尽管我进入NetStatusEvent函数并触发了netStream.seek(0);,但据我所知NetStream.Seek.Notify并没有任何作用。我正在使用NativeProcess,以下功能对此没有任何影响。

public function ProgressEventOutputHandler(e:ProgressEvent):void {
videoByteArray = new ByteArray();
nativeProcess.standardOutput.readBytes(videoByteArray, 0, nativeProcess.standardOutput.bytesAvailable);
netStream.appendBytes(videoByteArray);
}


我在这里想念什么吗?我在使用 netStream.seek(0);之前暂停了netStream。

编辑:

为了解决此问题,我按照VC的说明进行了以下操作:


videoByteArray = new ByteArray();移到我的init函数中,并且还在此函数中创建了 tempVideoByteArray = new ByteArray();
更新我的ProgressEventOutputHandler函数,以使其不再为videoByteArray创建新的ByteArray并更改此行- nativeProcess.standardOutput.readBytes(videoByteArray, videoByteArray.length, nativeProcess.standardOutput.bytesAvailable);


我没有做任何其他更改,现在视频将无法加载。如果我允许在ProgressEventOutputHandler函数内部创建新的ByteArray,则视频会再次加载。

最佳答案

精简版 :

试试我粘贴在这里的代码:Github Snippet链接

长版:

这个有点长,但希望它能一劳永逸...不用担心砖墙上的东西,墙壁被打碎了。为了激发您的灵感,请查看VC:One实验室使用appendBytes进行的内部演示:


MP4 Seeking Experiment:研究appendBytes帧数据访问和时间/搜索处理。实时帧字节仅使用AS3代码从MP4转换为FLV格式。
Speed Adjust of Audio & Video:用于视频分离和效果实验中的实时MP3音频。需要MP4 / FLV文件以及音频轨道中的MP3数据。
Synchronised Video Frames:用于以相同帧号显示的多个视频。


PS:我将使用URLStream方法,因为这对于加载本地文件或在线文件的人来说是一个更有用的答案。您可以从urlstream.progressEvent更改为通常的nativeProcess.progressEvent
我知道FFMPEG,但只使用AIR制作了Android应用。因此,对于这种AIR / FFMPEG连接,您比我了解的更多。

另外,此答案还假设您正在将FLV与MPEG H.264视频和MP3或AAC音频一起使用。

ffmpeg -i input.mp4 -c:v copy -c:a mp3 -b:a 128k -ac 2 -ar 44100 FLV_with_MP3.flv

这个假设很重要,因为它会影响我们要寻找的字节类型。
对于以上带有H.264视频和AAC或MP3音频的FLV,我们可以期望以下内容(在搜索时):


由于这是MPEG,因此第一个视频标签将保留AVC解码器配置字节,而第一个音频标签将保留“音频特定配置”字节。此数据不是实际的媒体帧,只是像音频/视频标签一样打包。 MPEG回放需要这些。可以在MP4容器内的STSD元数据条目(MOOV原子)中找到相同的字节。现在,下一个找到的视频标签将(或应该)是视频的实际第一帧。
视频关键帧:从0x09开始,下一个第11个字节为0x17,第12个字节为0x01
音频TAG AAC:从0x08开始,下一个11个字节为0xAF,第12个字节为0x01
音频TAG MP3:从0x08开始,下一个第11个字节为0x2F,第12个字节为0xFF


1)字节复制和检查值:

您正在寻找代表视频“标签”的字节。除了元数据标签外,您现在可以期望“标签”表示音频或视频帧的容器。有两种方法可以将标记字节放入“临时字节数组”中(我们将其命名为temp_BA)。


ReadBytes(慢):提取source_BA的开始/结束范围内的各个字节值
WriteBytes(快速):立即复制source_BA中字节的开始/结束范围


Readbytes解释:告诉Source将其字节读入Target。源将从其当前偏移量(位置)开始向前读取直至其长度。继续阅读之前正确的源位置...
source_BA.readBytes( into Target_BA, Pos within Target_BA, length of bytes required );
执行完上述行后,“源”位置现在将向前移动以说明新的行进长度。 (公式:源新Pos = previousPos + BytesLengthRequired)。

Writebytes解释:告诉Target从Source复制一定范围的字节。自从已知信息(从源)复制以来,速度很快。目标从当前位置开始写...
target_BA.writeBytes( from source_BA, Pos within source_BA, length of bytes required );
在执行上述行后,请注意,“源”和“目标”位置均未更改。

使用上述方法可将所需的标记字节从特定的temp_BA放入source_BA.position = x

要检查任何字节(其值),请使用以下方法更新某些int类型的变量:


阅读one-byte value:使用my_Integer = source_BA.readByte();
阅读two-byte value:使用my_Integer = source_BA.readUnsignedShort();
阅读four-byte value:使用my_Integer = source_BA.readUnsignedInt();
eight-byte value的变量Number:使用my_Number = source_BA.readDouble();


注意:不要混淆.readByte();,它提取(字节的)数字值与类似的.readBytes()听起来很像,将一个字节块复制到另一个字节数组。

2)查找视频关键帧(或I帧):

[带关键帧H264 / AAC的视频标签的插图图像]

查找视频关键帧


从起始偏移量开始,使用while循环现在[向前]遍历字节,在每个字节中搜索<9>的one-byte value(十六进制:0x09),发现后我们再检查前面的字节以确认实际上,这是一个真实的关键帧,而不仅仅是随机出现的“ 9”。
对于H.264视频编解码器,在正确的“ 9”字节位置(xPos),我们期望前面的第11和第12个字节分别分别为“ 17”和“ 01”。
If== true,然后检查三个“标记大小”字节,并在此整数上加上15,以获取预期从源写入目标(temp_BA)的字节的总长度。我们添加了15,以说明预期TAG DATA之前的11个字节和之后的4个字节。标签末尾的这4个字节是“上一个标签大小”,该数量实际上包括11个前字节,但不计算这些末尾4个字节本身。
我们告诉temp_BA从“ 9”字节(xPos)的pos开始写入Source(您的videoByteArray)字节,长度为“ Tag Size” +15。现在,您已经提取了一个MPEG关键帧。示例:temp_BA.writeBytes( videoByteArray, int (xPos), int (TAG_size) );
现在,可以使用以下键添加带有关键帧标记的temp_BA
示例:netStream.appendBytes( temp_BA ); //displays a single frame


注意:要读取3个字节的标签大小,我将显示一个自定义的转换bytes_toInt()函数(因为处理器一次读取整数的1个,2个或4个字节,此处读取3个字节是一个笨拙的请求)。

搜索提示:标签始终在跟踪中彼此跟随。我们还可以通过检查字节是否用于非关键帧(P帧)视频标签甚至某些音频标签来更快地查找。如果是这样,那么我们检查那个特定的tag size并现在增加我们的xPos来跳过这个新长度。这样,我们可以跳过整个标签大小,而不仅仅是跳过单个字节。仅在具有关键帧标记时停止。

3)从视频关键帧播放:

当您考虑它时,播放就像是逐帧进行自动搜索。视频的编码帧速率定义了获取下一帧的预期速度。

因此,您的播放功能可以简单地是Timer,它每秒获取X量的视频标签(帧)(或1000毫秒)。您以my_Timer = new Timer ( video_FPS )为例进行操作。当计时器运行并到达每秒钟FPS片时,它将运行append_PLAY();函数,而该函数又运行get_frame_Tag();函数。


NS.seek(0):将NetStream置于“搜索模式”。 (数字并不重要,但必须存在于命令中)。清除所有“提前帧”缓冲区,直到(。)帧才会更新。
RESET_SEEK:结束“搜索模式”,现在允许图像更新。使用RESET_SEEK命令后附加的第一个标签必须是带有视频关键帧的标签。 (对于仅音频,这可以是任何标签,因为从技术上讲,所有音频标签都是音频关键帧)
END_SEQUENCE :(对于MPEG H.264)播放所有剩余的“超前帧”(填充缓冲区)。耗尽后,您现在可以附加任何类型的视频代码。请记住,H.264需要向前移动的时间戳,如果看到像素变小,则您的下一个标记时间戳是错误的(太高或太低)。如果仅添加一帧(海报图像?),则可以使用END_SEQUEMCE清空缓冲区并显示该一帧(而无需等待缓冲区先填充x数量的帧)...


播放功能充当中间人功能来管理事物,而不会使If语句等弄乱get frame功能。例如,管理事物意味着检查是否下载了足够的字节,甚至根据Tag Size开始获得帧。

4)一个工作示例的源代码:

代码太长。.参见下面的link
https://gist.github.com/Valerio-Charles-VC1/657054b773dba9ba1cbc

希望能帮助到你。风投

关于actionscript-3 - AS3 NetStream AppendBytes寻求问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32182580/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com