Why is NetStream metadata reading wrong video duration?

61 Views Asked by At

I am trying to play and control a video, and one of key elements I need to control it is it's duration. I wrote a function that plays, pauses, resumes and stops videos, but, if I use slider to seek video near the end, I get an error saying that time is wrong.

I tried to trace time and to subtract 0.5 and 1 second. In that case, video is 2-5 seconds longer than expected?! Wierd.

myVideoData = new Video();
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
ns.client = {};
ns.client.onMetaData = ns_onMetaData;
ns.client.onCuePoint = ns_onCuePoint;
myVideoData.attachNetStream(ns);
ns.play(menu.videolist.selectedItem.data); //Video is loading and playing just fine

function ns_onMetaData(item: Object): void {
    myVideoDataW = item.width;
    myVideoDataH = item.height;
    myVideoDuration = item.duration;
    //Below this line is added for testing.
    ns.seek(item.duration); //It fails as Error #2044: Unhandled NetStatusEvent:. level=error, code=NetStream.Seek.InvalidTime
    //Tried to ns.seek(item.duration-1); and it works, except it seeks video not 1, but 2-5 seconds, depending on video length
    //I have same issue for every video, and I have tried like... 50-ish...
}

I just want to know is it about the code, about me...? Is it possible that all 50 videos I have tried have same problem? Sources of my videos are from my phone, from youtube, from professional web stores. All files are mp4!

1

There are 1 best solutions below

2
VC.One On BEST ANSWER

(1)

"...If I use slider to seek video near the end, I get an error saying that time is wrong."

Make sure myVideoDurationis known or set to = 0; as starting point. For example: Since your ns_onMetaData function updates the duration, there you could also enable seeking with a:

mc_Seekbar.addEventListener(MouseEvent.CLICK, on_click_SeekBar );

Then you could use this logic to seek:

function on_click_SeekBar (evt:Event = null) :void
{
    var myTime:int = (myVideoDuration / mc_Seekbar.width ) *  mc_Seekbar.mouseX;
    trace(">>> Seeking to : " + myTime + " seconds");
    ns.seek( myTime );
}

(2)

"Why is NetStream metadata reading wrong video duration?

ns.seek(item.duration);

It fails as Error #2044: Unhandled NetStatusEvent:. level=error, code=NetStream.Seek.InvalidTime"

That's because .duration is a Number data-type but .seek actually expects an int value.

The difference is... Number = 16.005; vs int = 16;. Number includes a decimal point. NetStream's .seek expects a whole numerals without fractions (basically: Just use integers, no decimal points).

Solution:
Simply cast the .duration into an int data type.

ns.seek( int(item.duration) );

Here's a testable example based on your code. Give it a file called video.mp4 at same location as compiled.

var myVideoData :Video = new Video();
var nc = new NetConnection(); nc.connect(null);
var ns :NetStream = new NetStream(nc);
ns.client = {};
ns.client.onMetaData = ns_onMetaData;
//ns.client.onCuePoint = ns_onCuePoint;
myVideoData.attachNetStream(ns);

var myVideoDuration:int, myVideoDataW:int, myVideoDataH:int = 0;

addChild(myVideoData);
//ns.play(menu.videolist.selectedItem.data); //Video is loading and playing just fine
ns.play("video.mp4");

function ns_onMetaData(item: Object) :void 
{
    myVideoDataW = item.width;
    myVideoDataH = item.height;
    myVideoDuration = item.duration; //update Int with duration
    
    //# Below this line is added for testing.
    ns.seek( int(item.duration) ); //option A: cast the Number to Int
    //ns.seek( myVideoDuration ); //option B: use an Int value
    trace("duration ( item.duration ) : " + ( item.duration) + " seconds.");
    trace("duration (myVideoDuration) : " + ( myVideoDuration) + " seconds.");
    
}