AS3 NetStream lags on first frame - actionscript-3

I'm developing an application in Adobe Air to display videos for a museum exhibit at a resolution of 2560x1440. The application works without a hitch on my machine, but when I run it on another (less powerful) computer, it does not function as intended. I've texted the application on two machines besides my own.
The problem is when one of the videos is called up, the video is called up and displays the first frame of the video and lags there for a good number of seconds (5-10), however I can still hear audio. After about 8-10 seconds, the video plays back as if it had been playing before and stutters briefly (1-2 seconds) before resuming playback normally. This is consistent behavior every time a video is launched as long as it's a fairly large video (> 50 MB as far as I can tell).
This does not happen on my development machine, which has a GTX 980 graphics card in it, but besides that and the motherboard, I can't think of any differences between the specs of the multiple machines.
The video throws an event indicating the buffer is full immediately as a video is launched, so buffering doesn't seem to be the issue.
Edit: Code (Pastebin)
Edit 2: Figured out it was the first frame, not a black screen

Still not entirely sure where the root of the problem lies, but what fixed it was adding this code right after calling the video. What it does is pause the playback and add a timer for one second, then seek 0.5 seconds into the video. I haven't run tests with this yet beyond getting past that first frame lag, but it works.
ns.pause();
var hesitate:Timer = new Timer(1000, 1);
hesitate.addEventListener(TimerEvent.TIMER_COMPLETE, function(e:TimerEvent)
{
ns.seek(0.5);
ns.resume();
});
hesitate.start();

Related

HTML5 video buffering despite waiting for `canplaythrough` event to `play()`

I'm trying to ensure (to the extent possible) that an HTML5 video begins playing only only when it is able to play through completely without buffering. For context, the MediaStream of the video is then used to mix with another audio source and sent over peer WebRTC connections. The videos are typically 5-10MB and a few minutes long (i.e. a decent broadband connection should have no trouble loading the entire video well before it's done playing).
To achieve this, my code currently waits for the canplaythrough event on the video element to begin and calls play() when it fires.
This "works" in the sense that the video begins playing and, in most cases, buffering is sufficient for the video to play through uninterrupted. But, in a few cases (specifically for two people so far that happen to both have been running Chrome on MacBook Airs and with apparently not incredible but decent broadband Internet connections) the video plays staggered and choppy---which I believe to mean the video has not sufficiently buffered.
Are there better techniques for either ensuring that video is sufficiently buffered on most browsers?
Would using fetch() to buffer the entire video in memory probably do the trick? Or is a resulting blob() also actually lazily buffered behind the scenes?
Are there good practices for testing and debugging these sorts of issues given that I can't really replicate this locally?
I have built a tool called Stream or Not that might help on the network side. It will tell you how long the video takes to start, how many stalls, etc. You can use your browser's devTools to throttle the network (and in Chrome, you can emulate the CPU).
Honestly - to see if the network is the issue, as long as the bitrate (use FFprobe https://www.streamclarity.com/probe?url=) is lower than the network speed, you are not network constrained.
There is another possibility. What are the dimensions of your video? How what are the dimensions of the viewport on the browser? If you are asking the device to chop down a lot of pixels - the playback limit might move away from bandwidth to CPU processing speed. I have seen this happen on mobile devices and on older Macs trying to play 4k videos - there just isn't enough CPU to process that many pixels.
I'd test the network speeds, just to be sure.
Make sure you are not sending more pixels than you need. Underpowered devices will have issues.

Flash AS3 erratic scrubber

Introduction
I made a video player that plays .mp4 files. It is based upon the FLVplaybackcomponent 2.5 in Flash Pro CS 5. It's basically a component with a movieclip interface (not a skin). the video plays fine, play/pause works and all that jazz.
Problem
The scrubber is erratic.
It seems to only be able to scrub in 10 second intervals and often behaves oddly (jumping to wrong locations).
All I seem to be doing is to take the total video time. Applying that time to a slider component so minimum is 0 and maximum is total video time. Then when the user changes the slider value it sets the playheadtime equal to the slider value.
If I trace out the values it seems fine, but the playheadtime is misbehaving.
If the slider displays 16 seconds and the playhead is made equal to 16 seconds it seems to snap at the closest 10 second interval.
Source
Here is a test file showcasing the problem:
http://rosefalk.dk/stuff/temp/stackoverflow/videoplayer_no_js.html
Here is the source with video and .fla: http://rosefalk.dk/stuff/temp/stackoverflow/stackoverflow-scrubberproblem.zip
BONUS
HTML players in some browsers seem to have no problem scrubbing the file.
The video service used (DigiZuite) seems to re-encode the video with keyframes every 10 seconds. Re-encoding the video with keyframes every second fixed the problem (small video so it was VERY noticeable).

Flash Player behaviour when lost focus

I've got a real problem with FlashPlayer. What I need is to have it working on full speed when it is in the THROTTLE mode - that means when FlashPlayer loose its focus and decrease framerate to about 4fps. This is commonly know as a feature for mobile phones or when you change a tab in your browser and your .swf movie doesn't run with full speed anymore.
I need this full speed because we run tests with flash swfs on virtual servers, and unfortunatelly tests run very long.
I found that in FP11.2 was ThrottleEvent introduced that inform you what Flash Player is doing. It can go to PAUSE, THROTTLE, or RESUME state. Unfortunatelly it seems that I can't force other stage.frameRate when it really goes into any of these states. I tried also with Event.DEACTIVATE, and Event.ACTIVATE without any results.
Can I go around this any way? Or if not, what version of FlashPlayer was the latest before Adobe incorporated this feature into FP?
Thanks for any response!
Kindest Pawel
you should try
stage.addEventListener(ThrottleEvent.THROTTLE, doStuff)

Play HTML5 Audio immediately without waiting for the entire buffering to complete?

I have a very fast connection and it takes about 2-3 seconds before the song actually starts playing. It's a relatively average 128kbps MP3 size (3mb-4mb). I have set preload="auto" but that didn't help much. Is there a way to just start playing the audio right away and continue to buffer it (sort of like YouTube does)?
Here is an example that I am currently working on. It's going to play an audio simultaneously on all connected clients. So if you have 2+ laptops, you can try it out. All computers must be connected before you start playing the audio. (double click on a song to start playing).
Running video and audio without complete buffering is called smooth / adaptive streaming. It can be achieved in players like silverlight and flash.
What it actually does is to create chunks of files and let the user play file chunk by chunk. Since you are downloading chunks, it will not require whole file to download.
Well, I am not giving you the full fledged answer since I haven't studied much but I am giving you the exact idea of how it works.
I had same issue but with HTML5 Video.. I overcame it with using Smooth streaming media Azure..
Here is a tutorial of the same : http://www.wrapcode.com/featured/windows-azure-media-services-mp4-to-smooth-streaming/
I will keep you updated once I find something useful :-)
If you use preload=none, then you have no buffer at the beginning but it will buffer your content "on the fly"
I have an Icecast server which streamsmy contet, and when I use pause and play, it buffers my content, even with preload=none.
Do not use preload=auto. It will take some time to start.

FLV performance and garbage collection

I'm building a large flash site (AS3) that uses huge FLVs as transition videos from section to section. The FLVs are 1280x800 and are being scaled to 1680x1050 (much of which is not displayed to users with smaller screens), and are around 5-8 seconds apiece. I'm encoding the videos using On2's hi-def codec, VP6-S, and playback is pretty good with native FLV players, Perian-equipped Quicktime, and simple proof-of-concept FLV playback apps built in AS3.
The problem I'm having is that in the context of the actual site, playback isn't as smooth; the framerate isn't quite as good as it should be, and more problematically, there's occasional jerkiness and dropped frames (sometimes pausing the video for as long as a quarter of a second or so). My guess is that this is being caused by garbage collection in the Flash player, which happens nondeterministically and is therefore hard to test and control for.
I'm using a single instance of FLVPlayback to play the videos; I originally was using NetStream objects and so forth directly but switched to FLVPlayback for this reason. Has anyone experienced this sort of jerkiness with FLVPlayback (or more generally, with hi-def Flash video)? Am I right about GC being the culprit here, and if so, is there any way to prevent it during playback of these system-intensive transitions?
Jerkiness in FLV/F4V playback is hardly the result of garbage collection - the video is actually kept in memory until it is fully unloaded, so there's no garbage collection taking place at all (unless you've done something unorthodox like placing the video on a container with cacheAsBitmap set to true).
Switching to F4Vs if you don't need specific FLV features (like the link posted by daidai suggests - disclaimer, it's my blog) would help, but overall, you also have to be aware of anything that's impacting compositing of the video on screen. Because a big size video forces everything that's overlapping it to be re-rendered, any small object can have a big impact on performance.
Do you have things on top of the video? Try getting rid of them, if possible, or setting cacheAsBitmap to true (if they're not animated). This is specially good for complex vector drawings or text (bitmaps/images are much faster to draw). If they have different blending modes, you're sort of screwed - can you use the normal blending mode instead?
Do you have anything below the video? If so, get rid of them while the video is playing (just set visibility to false).
To check on unnecessary renderings, somehow pause the video, right-click, turn on 'show redrawn regions' (debug player). Do you see the red square drawing continuously? Then there's something happening there on the background, better to get rid of it.
Do you have anything happening on the background via onEnterFrame or timers/intervals? Try pausing it.
Is your video 30fps, and a CG rendering (eg, can use motion blur)? If yes, try rendering at 24fps instead, or something between - still good quality, but much less data to decode and draw.
Can you use smaller videos? Even if you're still rendering them at the same bigger size, less pixel data to decode and render helps immensely, and the impact in quality can be pretty small.
That pretty much sums it all. Getting rid of everything else on screen is usually your #1 priority though.
Have you tried encoding the videos in H.264 instead? Flash player supports them for some time now, it may end up working better. That's what most people doing HD video in Flash use (eg Youtube, Vimeo, etc).
Just as a test, try plaing a 1080p HD video on youtube and see if that pauses at all for you.
Check out http://zehfernando.com/2010/benchmarking-video-playback-performance-in-flash/