Flex application not releasing video after playback - actionscript-3

I have a Flash Builder 4.6 program that plays multiple video files. After each video plays, I want to release it. If I use Process Explorer, I can still see that the videos are not released when they have finished playing. This application is for training and one session may have upwards of 40 videos and about 1,800 people viewing a day.
I have the following to create and destroy the player.
hmpe = new VideoElement(new URLResource(src));
hostVideo.addMediaElement(hmpe);
hmp = new MediaPlayer();
hmp.play();
hmp.addEventListener(MediaPlayerStateChangeEvent.MEDIA_PLAYER_STATE_CHANGE,MediaPlayerStateChange);
hmp.addEventListener(PlayEvent.PLAY_STATE_CHANGE, PlayStateChange);
hmp.addEventListener(TimeEvent.CURRENT_TIME_CHANGE, onTimeChange);
hmp.addEventListener(TimeEvent.COMPLETE,onTimeChange);
hmp.media = hmpe;
...
// To remove when stop is reached in PlayStateChange
hostVideo.removeMediaElement(hmpe);
hmpe = null;
hmp = new MediaPlayer();
Why is the file not released?

Ok, here's what I did inside PlayStateChange, stop, to release the files.
hostVideo.removeMediaElement(hmpe);
hostVideo = new MediaContainer();
hmpe = null;
hmp.media = null;
hmp = new MediaPlayer();

Related

How to Improve FLVPlayback - Reduce Choppy Video

I have a 1920x1080 video playing inside a flash project with the same dimensions, using Firefox. The project is using CC2015, Latest Flash Player, Latest FF. I should note that this project is using locally stored videos.
I'm using AS3, FLVPlayback component, and the videos have been compressed (by production).
Heres the code that uses the playback component
function playVideoByString(source: String): void {
hideTheButtons();
attractTimer.stop();
movie_container = new MovieClip();
addChild(movie_container);
movie_container.x = 0;
movie_container.y = 0;
launchVideo(movie_container, source);
}
function launchVideo(vBox, vFile): void {
attractTimer.stop();
flvPlayer = new FLVPlayback();
flvPlayer.source = vFile;
flvPlayer.skinAutoHide = true;
flvPlayer.skinBackgroundColor = 0x000000;
flvPlayer.width = 1920;
flvPlayer.height = 1080;
flvPlayer.autoRewind = false;
cuePt.time = 0.9;
cuePt.name = "ASpt1";
cuePt.type = "actionscript";
flvPlayer.addASCuePoint(cuePt);
vBox.addChild(flvPlayer);
// adding listeners in here
flvPlayer.addEventListener(MetadataEvent.CUE_POINT, cp_listener);
flvPlayer.addEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
}
Playback is experiencing some degradation in the form of what looks like frames dropping, or "stutter." The animations look glass smooth when the MP4 is opened in Firefox and played back using FFs player. They also look fine when played in QuickTime (obviously). The video is 30FPS, as is the Flash Project, though from what I understand, FLVPlayback will use the videos encoded frame rate regardless of Flash's FPS.
Is there anything I can do to improve the video playback, and possibly smooth the videos out without loosing quality?

flash/AS3 netstream loading/buffering very slow, what am I missing?

My custom movieplayer uses the following code for playing video. It takes a really long time for the clip to start playing, but once it does, you can skip directly to the end.
I have a feeling that there is some knowledge I'm missing in how buffers and preload works. Could somebody send me in the right direcion?
private function init(e:Event = null):void {
connection = new NetConnection();
connection.addEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
connection.addEventListener(IOErrorEvent.IO_ERROR, doIOError);
connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, doSecurityError);
connection.connect(null);
stream = new NetStream(connection);
stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, doAsyncError);
stream.addEventListener(NetStatusEvent.NET_STATUS, doNetStatus);
stream.addEventListener(IOErrorEvent.IO_ERROR, doIOError);
stream.client = this;
video = new Video(1024, 576);
mc = new MovieClip();
mc.addChild(video);
stage.addChild(mc);
mc.addEventListener(MouseEvent.CLICK, onClick);
video.attachNetStream(stream);
stream.bufferTime = 5;
stream.receiveAudio(true);
stream.receiveVideo(true);
stream.play(SITEURL + vidID +".mp4");
}
You can see the player in action here: http://joon.be/serve/ngjd_player.swf
Apparently the video's weren't streaming because I needed to run QT FastStart on them.
This solved the problem, netstream is now running as expected.
You can download qt-faststart.exe and then in admin command promt run:
qt-faststart.exe "source.mp4" "fixed.mp4"
Took about 15-30 seconds for 10 minutes long video.
Credit: https://articulate.com/support/article/mp4-movie-doesnt-begin-playing-until-it-has-fully-downloaded
I also tried this free opensource converter HandBrake with Web Optimized checked. (took all 10 minutes to convert)

Getting metadata from multiple preloading video

I found out that I could only get the metadata of the 1st video I clicked. How does metadata works? It could only load once before the video ends?
Here's some example what I'm doing
//will be adding new video when this function is called
public function set newVideo():void
{
videoProperties();
}
public function videoProperties():void
{
meta=new Object()
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
nsArray[dList.currentIndex] = ns;
nsi = nsArray[dList.currentIndex];
// Add the buffer time to the video Net Stream
nsi.bufferTime = buffer;
// Set client for Meta Data Function
nsi.client = {};
nsi.client.onMetaData = onMetaData;
nsi.addEventListener(AsyncErrorEvent.ASYNC_ERROR,asyncErrorHandler);
nsi.addEventListener(NetStatusEvent.NET_STATUS, onNetStatusEvent);
nsi.play(videoURL);
nsi.pause();
nsi.seek(-1);
}
private function onMetaData(info:Object):void
{
//some video duration calculations
}
I tried to load all the metadata at once, but seems like it needs the video to be play only it will manage to get the metadata.
Are you trying to get the metadata without starting the video loading process? If so, that's not possible with actionscript alone. That said, since flvs load progressively you don't need to load an entire video to get at the meta data. You can load each video and stop loading it when you've got the metadata.

if I load a flv with netStream, how can I call a function when the flv stops playing

I have a website in ActionScript 3 that has lots of FLV animations that happen when you press buttons. Right now this is how I have it set up.
in AS3,
im loading FLv's (which are animations I exported in FLV form from After Effects)
with net stream. I have a timer set up for the same amount of length of time that the animations (FLV's) play and when the timer stops it calls a function that closes the stream, opens a new one and plays another video. The only problem I noticed using timers is that if the connection is slow and (animation)stops for a second, the timer keeps going, and calls the next flv too early.
Does anyone know a way to load a flv, or swf for that matter, at the end of play of the flv? so that the next FLV will always play at the end of the run time of the previous FLV, rather than using timers?
im thinking onComplete but I don't know how to implement that!?
Sequential playing is pretty easy to achieve with the OSMF framework, you should check it out. Google "osmf tutorials" and you should find a few tutorials online.
The framework is fairly recent, but it looks like it may become the de facto solution for media delivery in Flash as it's not limited to video but also audio & images.
As a developer you won't have to bother with the NetStream & NetConnection classes. Developing video solutions , as well as audio & images solutions should be streamlined and easier to handle. Only limitation is that it requires Flash 10
Here's some code for checking when a FLV ends with NetStream. I just provide snippets as I assume you got the FLV up and running already.
//create a netstream and pass in your connection
var netStream:NetStream = new NetStream(conn);
//add callback function for PlayStatus -event
var client : Object = {};
client.onPlayStatus = onPlayStatus;
netStream.client = client;
//attach your NetStream to the connection as usual
//---
//function that gets called onPlayStatus
function onPlayStatus(info : Object) : void {
trace("onPlayStatus:" +info.code + " " + info.duration);
if (info.code == "NetStream.Play.Complete") {
//play the next FLV and so on
}
}
EDIT: With your example code it will look something like this.
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
var listener:Object = new Object();
listener.onMetaData = function(md:Object):void{};
listener.onPlayStatus = function(info : Object) : void {
trace("onPlayStatus:" +info.code + " " + info.duration);
if (info.code == "NetStream.Play.Complete") {
//play the next FLV and so on
}
};
ns.client = listener;
vid1.attachNetStream(ns);
const moviename1:String = "moviename2.flv";
const moviename1:String = "moviename3.flv";
var movietoplay:String = "moviename.flv";
ns.play(movietoplay);

Actionscript 3: Monitoring the activity level for multiple Microphones doesn't seem to work

For a project I want to show all available webcams and microphones, so that the user can easily select whichever webcam/microphone combination they prefer. I run into an issue with the microphones listing though.
Each microphone is listed with an activity animation and it's name. I am able to list all Microphones just fine (using the Microphone.names Array), but it seems like I can only get the activity viewer to work for one microphone. The other microphones show up with '-1' activity, which (as far as I know) is Flex for 'present, but not in use'. When unplugging the microphone that does show activity, the next one (in my case, the mic-in line on my motherboard) shows up with '0' activity (it's not connected, so that makes sense).
During my testing I have a total of 3 microphones available, the not-connected onboard mic-in port, and two connected microphones.
For testing purposes I use a timer that traces the current microphone activity each 100ms and the graph is also shown.
It does not seem to matter what default microphone I set via flash' settings panel.
The code
I've only attached the revelant code snippets below to make it easier for you to read through them. Please let me know if you prefer the entire code.
Main application.mxml
Note: cont is a VBox. i is defined before this code snippet.
var mics:Array = Microphone.names;
for(i=0; i < mics.length; i++){
var mic:settingsMicEntry = new assets.settingsMicEntry;
mic.d = {name: mics[i], index: i};
cont.addChild(mic);
}
assets/settingsMicEntry.mxml
timer is defined before this code snippet. the SoundTransform is added to silence local microphone playback. Excluding this code does not solve the problem, sadly (I've tried). display is an MXML Canvas object.
mic = Microphone.getMicrophone(d.index);
if(mic){
// Temporary: The Microphones' visualizer
var bar:Box = new Box();
bar.y = 50;
bar.height = 0;
bar.width = 66;
bar.setStyle("backgroundColor", 0x003300);
display.addChild(bar);
var tf:SoundTransform = new SoundTransform(0);
mic.setLoopBack(true);
mic.soundTransform = tf;
timer = new Timer(100);
timer.addEventListener(TimerEvent.TIMER, function(e:TimerEvent):void{
var h:int = Math.floor((display.height/100)*mic.activityLevel);
bar.height = (h>-1) ? h : 0;
bar.y = (h>-1) ? display.height-h : display.height;
trace('TIMER: '+h+' from '+d.name);
});
timer.start();
}
I'm pulling my hear out here, so any help is much appreciated!
Thanks,
-Dave
Ps.: Pardon the messiness of the code!
You can set up a mock NetStream connection using the OSMF library.
You'll need to import the classes from the NetMocker project (under libs/adobe - org.osmf.netmocker) and the classes NetConnectionCodes and NetStreamCodes (under framework/OSMF - org.osmf.net).
Check out that you need to create one NetStream for each microphone