在 AS3 中,当使用 NetStream 进行视频播放时,当我使用appendBytes 时如何查找

发布于 2024-09-25 14:47:43 字数 276 浏览 9 评论 0原文

我正在尝试使用 NetStream 从 byteArray 播放。请参阅了解我正在谈论的内容。

我能够让它播放视频。但现在我需要能够看到特定的一秒。我无法做到这一点。如果我浏览字节数组,我知道我可以根据需要获取元数据和关键帧以及每个关键帧所在位置的偏移量(以字节为单位)。然而,没有办法寻求特定的偏移量。它只支持以秒为单位的查找,这似乎不适用于 byteArray。

我该怎么办?

I am trying to use NetStream to play from a byteArray. Please see this for what I am talking about.

I am able to get this to play the video. However now I need to be able to see to a particular second. I am not able to do this. If I go through the bytearray I know I can get the metadata and the keyframes as required and the offset ( in bytes) as to where each keyframe is at. However there is no way to seek to a particular offset. It only supports seek in seconds and that doesn't seem to work on the byteArray.

How do I go about this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

临走之时 2024-10-02 14:47:43

我得到了我的工作:

// onmetadata function get all timestamp and corresponding fileposition..

function onMetaData(infoObject: Object): void {

    for (var propName: String in infoObject) {

        if (propName == "keyframes") {
            var kfObject: Object = infoObject[propName];
            var timeArr: Array = kfObject["times"];
            var byteArr: Array = kfObject["filepositions"];

            for (var i: int = 0;i < timeArr.length;i++) {
                var tagPos: int = byteArr[i]; //Read the tag size;
                var timestamp: Number = timeArr[i]; //read the timestamp;
                tags.push({
                    timestamp: timestamp,
                    tagPos: tagPos
                });

            }
        }

// onseek click get approximate timestamp and its fileposition
protected

function seek_click(seektime: Number): void {

    var cTime: Number = 0;
    var pTime: Number = 0;

    for (var i: int = 1;i < tags.length;i++) {
        cTime = tags[i].timestamp;
        pTime = tags[i - 1].timestamp;

        if (pTime < seektime) {
            if (seektime < cTime) {
                seekPos = tags[i - 1].tagPos;
                stream.seek(pTime);
                break;
            }
        }
    }
}

/// append bytes on seekposition
private

function netStatusHandler(event: NetStatusEvent): void {

    switch (event.info.code) {

    case "NetStream.Seek.Notify":
        stream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);

        totalByteArray.position = seekPos;

        var bytes: ByteArray = new ByteArray();
        totalByteArray.readBytes(bytes);
        stream.appendBytes(bytes);

        stream.resume();
        break;
    }
}​

I got I worked:

// onmetadata function get all timestamp and corresponding fileposition..

function onMetaData(infoObject: Object): void {

    for (var propName: String in infoObject) {

        if (propName == "keyframes") {
            var kfObject: Object = infoObject[propName];
            var timeArr: Array = kfObject["times"];
            var byteArr: Array = kfObject["filepositions"];

            for (var i: int = 0;i < timeArr.length;i++) {
                var tagPos: int = byteArr[i]; //Read the tag size;
                var timestamp: Number = timeArr[i]; //read the timestamp;
                tags.push({
                    timestamp: timestamp,
                    tagPos: tagPos
                });

            }
        }

// onseek click get approximate timestamp and its fileposition
protected

function seek_click(seektime: Number): void {

    var cTime: Number = 0;
    var pTime: Number = 0;

    for (var i: int = 1;i < tags.length;i++) {
        cTime = tags[i].timestamp;
        pTime = tags[i - 1].timestamp;

        if (pTime < seektime) {
            if (seektime < cTime) {
                seekPos = tags[i - 1].tagPos;
                stream.seek(pTime);
                break;
            }
        }
    }
}

/// append bytes on seekposition
private

function netStatusHandler(event: NetStatusEvent): void {

    switch (event.info.code) {

    case "NetStream.Seek.Notify":
        stream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);

        totalByteArray.position = seekPos;

        var bytes: ByteArray = new ByteArray();
        totalByteArray.readBytes(bytes);
        stream.appendBytes(bytes);

        stream.resume();
        break;
    }
}​
月竹挽风 2024-10-02 14:47:43

每个 flv 标签都有一个时间戳和偏移量。
您可以在此处找到 FLV 规范:http://download.macromedia.com/f4v/video_file_format_spec_v10_1。 pdf

您无法在任何位置播放视频。您必须从标签的开头开始,这样您就需要找到时间最接近您要查找的时间的标签。

你会想要做这样的事情:

private var tags:Array = [];
private var fileStream:FileStream;  
private var netStream:NetStream;
private var seekTime:Number;

public function function readTags(path:String):void
{
    //open the fileStream for reading

    while(fileStream.bytesAvailable > 0)
    {
        //sudo code for reading the tags of an FLV

        var tagPosition:int = fileStream.position;
        var tagSize:int = //Read the tag size;
        var timestamp:int = //read the timestamp;
        tags.push({timestamp:timestamp, position:tagPosition}];
        fileStream.position += tagSize;  //goto the next tag
    }
}

private function findTagPosition(timeInMilliseconds:int):int
{
    //Search the tags array for the tags[a].timestamp that is nearest to timeInMilliseconds

    return tags[indexOfTagNearstToTimeInMilliseconds].position;
}

public function seek(time:Number):void
{
    seektime = time;
    netStream.seak(time);
}

private function onNetStatusEvent(event:NetStatusEvent):void
{
    if(event.info.code == NetStreamCodes.NETSTREAM_SEEK_NOTIFY)
    {
        fileStream.position = findTagPosition(seekTime * 1000);
        netStream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);
        var bytes:ByteArray = new ByteArray();
        fileStream.readBytes(bytes);
        netStream.appendBytes(bytes);
    }
}

Each flv tag has a timestamp and offset.
You can find the FLV spec here: http://download.macromedia.com/f4v/video_file_format_spec_v10_1.pdf

You can't play the video at any position. You must start at the beginning of a tag so you will need to find the tag with a time nearest to the time you want to seek to.

You're going to want to do something like this:

private var tags:Array = [];
private var fileStream:FileStream;  
private var netStream:NetStream;
private var seekTime:Number;

public function function readTags(path:String):void
{
    //open the fileStream for reading

    while(fileStream.bytesAvailable > 0)
    {
        //sudo code for reading the tags of an FLV

        var tagPosition:int = fileStream.position;
        var tagSize:int = //Read the tag size;
        var timestamp:int = //read the timestamp;
        tags.push({timestamp:timestamp, position:tagPosition}];
        fileStream.position += tagSize;  //goto the next tag
    }
}

private function findTagPosition(timeInMilliseconds:int):int
{
    //Search the tags array for the tags[a].timestamp that is nearest to timeInMilliseconds

    return tags[indexOfTagNearstToTimeInMilliseconds].position;
}

public function seek(time:Number):void
{
    seektime = time;
    netStream.seak(time);
}

private function onNetStatusEvent(event:NetStatusEvent):void
{
    if(event.info.code == NetStreamCodes.NETSTREAM_SEEK_NOTIFY)
    {
        fileStream.position = findTagPosition(seekTime * 1000);
        netStream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);
        var bytes:ByteArray = new ByteArray();
        fileStream.readBytes(bytes);
        netStream.appendBytes(bytes);
    }
}
锦上情书 2024-10-02 14:47:43

尝试我在此处发布的代码作为示例如何在不需要 FLV 元数据中存在“关键帧”的情况下完成查找。还有一个 可用于测试的工作演示(使用带有 H264 和 AAC/MP3 音频的 FLV)。

该代码部分是为了回答这个问题(如果您需要额外的信息/上下文)

Try my code posted here for an example of how seeking is done without needing "keyframes" to exist in FLV metadata etc. There is also a working demo available to test (use FLV with H264 and AAC/MP3 audio).

That code was partly to answer this question (if you need additional info/context)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文