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)
"...If I use slider to seek video near the end, I get an error saying that time is wrong."
Make sure myVideoDuration
is 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.");
}