I have been working in AS3 to stream 1080P video on YouTube and video gets start uploading and almost 4-5 minutes of the video has been uploaded successfully and afterwards YouTube shows that stream has been ended, but FFMPEG will never hits on "Exit" or any other method even after waiting for next 10 minutes.
Below is the method I am using.
public var _nativeProcessStartupInfo:NativeProcessStartupInfo;
public var _processArgs:Vector.<String>;
public var _process:NativeProcess;
protected function StartVideo_clickHandler(event:MouseEvent):void
{
_nativeProcessStartupInfo.executable = File.applicationStorageDirectory.resolvePath("ffmpeg.exe Path");
_processArgs.push('-re');
_processArgs.push('-i');
_processArgs.push(VideoPath);
_processArgs.push('-vcodec');
_processArgs.push('copy');
_processArgs.push('-acodec');
_processArgs.push('copy');
_processArgs.push('-maxrate');
_processArgs.push('4500k');
_processArgs.push('-bufsize');
_processArgs.push('9000k');
_processArgs.push('-pix_fmt');
_processArgs.push('yuv422p');
_processArgs.push('-preset');
_processArgs.push('fast');
_processArgs.push('-ac');
_processArgs.push('2');
_processArgs.push('-r');
_processArgs.push('30');
_processArgs.push('-g');
_processArgs.push('60');
_processArgs.push('-ar');
_processArgs.push('44100');
_processArgs.push('-f');
_processArgs.push('flv');
_processArgs.push(streamurl+'/'+streamname);
_nativeProcessStartupInfo.arguments = _processArgs;
_process = new NativeProcess();
_process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
_process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, progress);
_process.addEventListener(NativeProcessExitEvent.EXIT, onExit);
_process.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOErrorNativeProcess);
_process.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR, onIOErrorNativeProcess);
_process.start(_nativeProcessStartupInfo);
}
public function onIOErrorNativeProcess(event:IOErrorEvent):void
{
trace(event.toString());
}
public function onOutputData(event:ProgressEvent):void
{
trace("Got: ", _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable));
}
public function progress(e:ProgressEvent):void
{
trace(e);
}
public function onExit(e:NativeProcessExitEvent):void
{
trace(e);
}
I have tried with 720P video too by changing bit rate from 4500k to 2500k which is as per YouTube and it is working fine but with 1080P something not went as per expectation.
Here are the video details:
Resolution : 1920*1080
Data Rate : 3220kbps
FrameRate : 20
Thanks in advance
There is two problem with the following code.
In the "progress" function I am not reading actual log of the FFMPEG, have to update progress event like below.
public function progress(e:ProgressEvent):void
{
trace("Progress: ", _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable));
}
For now I have just traced the log and code is working properly in Debug mode after creating build issue has been happening and after that I have logged all the data in file and then even after creating build everything is working fine.
I don't know the exact reason behind it, but this solution help me for now.
Thanks
Related
IDE: FLASH CS6 Professional
SDK: AIR 18 for Android
I'm trying to use Workers for my app.
The problem is, it doesn't work that it suppose to be.
public class Main extends Sprite {
private var worker:Worker;
public function Main() {
var ba:ByteArray = this.loaderInfo.bytes;
if(Worker.current.isPrimordial){
worker = WorkerDomain.current.createWorker(ba);
worker.start();
trace("Created Main");
}else{
trace("Created Worker");
}
}
}
It should output
Created Main
Created Worker
but i'm only getting
[SWF] Test.swf - 2831 bytes after decompression
Created Main
[UnloadSWF] Test.swf
Test Movie terminated.
EDIT:
Ok i tried to publish the app and ran it. It works like it should be. But why doesn't it work when i try to ran it with Adobe Debug Launcher ?
This is what it looks like on Android Debug Launcher (ADL)
ADL
This is what it looks like when Published.
Published
EDIT 2:
Tried it with Flash Professional CC 2015. Upgraded to AIR SDK 19.0.0.213.
Still the same result. What a pain Adobe.
It should work, but Flash Pro CS6 doesn't show the worker's trace statements. Check flashlog.txt or send messages from the worker to the main SWF over a MessageChannel.
I made a lib to support use of Workers, if you want use you can check it in GitHub, it is open source project.. hope help ASWorker Link
The implementation is like this
package
{
import com.tavernari.asworker.ASWorker;
import com.tavernari.asworker.notification.NotificationCenter;
import com.tavernari.asworker.notification.NotificationCenterEvent;
import flash.display.Sprite;
public class ASWorkerDemo extends Sprite
{
private var asWorker:ASWorker;
//BOTH AREA
public function ASWorkerDemo()
{
//important know, all class start here will be replicated in all works.
asWorker = new ASWorker(this.stage, uiWorkerStartedHandler, backWorkerStartedHandler);
}
//BOTH AREA END
//UI AREA START
private function uiWorkerStartedHandler():void{
//implement all class or calls for your UI
NotificationCenter.addEventListener("FROM_BACK_EVENT_MESSAGE", onFromBackEventMessageHandler );
}
private function onFromBackEventMessageHandler(e:NotificationCenterEvent):void
{
trace(e.data);
if(e.data == "completed job"){
NotificationCenter.dispatchEventBetweenWorkers( new NotificationCenterEvent("NEXT_MESSAGE") );
}
}
//UI AREA END
//BACK AREA START
private function backWorkerStartedHandler():void{
//implement all class or calls for your BACK operations
NotificationCenter.addEventListener("NEXT_MESSAGE", uiCallForNextMessageHandler );
}
private function uiCallForNextMessageHandler():void
{
for(var i:int = 0; i < 15; ++i){
NotificationCenter.dispatchEventBetweenWorkers( new NotificationCenterEvent("FROM_BACK_EVENT_MESSAGE", false, i) );
}
NotificationCenter.dispatchEventBetweenWorkers( new NotificationCenterEvent("FROM_BACK_EVENT_MESSAGE", false, "completed job") );
}
// BACK AREA END
}
}
Good luck with Workers
Air 20.0.0.204 ADL is also not enjoying anything worker related (from my limited experimentation), however the desktop Flash Player seems to work just fine. This makes debugging convoluted and problematic when you are using Air specific libraries in your project and prefer not to wildcard variable types.
At the moment, workers are only supported on desktop platform. This Adobe developer's guide page specifically mentions "for desktop platforms".
Meanwhile, there is an AS3-Worker-Compat library by Jeff Ward that enables you to write code with Workers that will still work correctly in an environment that doesn't support Workers (of course, in this case your code will run in single-threaded mode).
I think many people are waiting for Adobe to implement workers for mobile, hopefully it will come in the future.
Here I have AS3 to for uploading recorded sound file to server. When I test it in Flash it works properly (record sound and upload it and goes to next frame) , but in browser it doesn't work. It seems can't call myUpload but I don't why? Is it should be mouse event? Thanks.
function VOCWordToYourMp3()
{
setTimeout(startRecording,3000);
recorder.addEventListener(RecordingEvent.RECORDING, onRecording);
recorder.addEventListener(Event.COMPLETE, onRecordComplete);
}
function startRecording()
{
if (! recording)
{
recorder.record();
}
else if (recording)
{
recorder.stop();
recording = false;
}
}
function onRecording(e:RecordingEvent)
{
//
}
function onRecordComplete(e:Event):void
{
//
}
function renderWav(src, convertToMp3 = false)
{
//
function handleRenderTimer(e:TimerEvent)
{
//
}
function finishRender()
{
//
}
}
function makeIntoMp3(wav)
{
wav.position = 0;
mp3Encoder = new ShineMP3Encoder(wav);
mp3Encoder.addEventListener(Event.COMPLETE, mp3EncodeComplete);
mp3Encoder.addEventListener(ProgressEvent.PROGRESS, mp3EncodeProgress);
mp3Encoder.start();
function mp3EncodeProgress(e:ProgressEvent):void
{
//
}
function mp3EncodeComplete(e: Event):void
{
myUpload('sound1',mp3Encoder.mp3Data);
}
}
function myUpload(namefile:String,sba: ByteArray):void
{
//upload code
}
Update:
In Flash Player 10 and Actionscript 3.0, all the calls to URLLoader must be in the same callstack.
http://helpx.adobe.com/flash-player/kb/user-interaction-required-upload-download.html
What is same callstack mean?
I recommend using something like Vizzy: https://code.google.com/p/flash-tracer/ to debug your swf in the browser. You can put trace statements into the onRecordComplete() and myUpload() functions, etc, to see how far the code is getting, and to see if you are getting any new errors. You may have some kind of security sandbox error because you are running in the browser. Being able to see what that error is will help you figure out what to do next.
To use Vizzy, you need to have the debug player running in your browser, and to configure the right path to your log file. This is sometimes a little bit tricky, so I'll give you some tips:
Add a file to your home directory called mm.cfg, and populate it with these settings:
ErrorReportingEnable=1
AS3Verbose=0
TraceOutputFileEnable=1
AS3Trace=0
TraceOutputBuffered=0
AS3StaticProfile=0
Then in Vizzy you have to set up the path to the log. On my windows 7 machine it is here:
C:\Users\MyUserName\AppData\Roaming\Macromedia\Flash Player\Logs\flashlog.txt
It may be different depending on your operating system.
Good luck, and report back if you Vizzy gives you any new information.
I am VERY new to this site! I have been reading the codes for the past few nights! From Publishing a flash project with network access so it can contact the internet to RTMP applications and streaming. But I have hit a wall and I do not want to go off the wrong path as most of my work is bits and pieces of helpful information on this site. And please appologize I'm not the boss of a company, so I do not do much of the coding any more and i have surely forgotten most of my PHP coding background, Please do not smite me for dumb or"noob". But since I have made it this far with the flash and actionscripts3 programming I thought it would not hurt if I asked a few questions from much smarter people!
Currently I am working on a single windowed flash project that will allow me to pull up to 12 live RTMP streams. Currently with everything i have been able to do, I have a working code so far to JUST pull a single RTMP string. Took me 3 days of code that was pulled off the internet, to get it to work. i have been successful in getting one stream with action script
package com.endseven {
import flash.events.NetStatusEvent;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import com.endseven.RTMPStream;
public class Downstream extends RTMPStream {
/* the constructor. */
public function Downstream():void {
trace("Downstream object has been created."); // debug trace..
this.oVideo = new Video(640, 480);
this.oConnection = new NetConnection();
this.oConnection.addEventListener(NetStatusEvent.NET_STATUS, eNetStatus, false, 0, true);
this.oConnection.connect(this.sMediaServerURL);
}
/* triggered when a net status event is received. */
private function eNetStatus(oEvent1:NetStatusEvent) {
trace("NetStatusEvent: " + oEvent1.info.code); // debug trace..
switch (oEvent1.info.code) {
case "NetConnection.Connect.Success":
// create a stream for the connection..
this.oNetStream = new NetStream(oConnection);
this.oNetStream.addEventListener(NetStatusEvent.NET_STATUS, eNetStatus, false, 0, true);
this.oNetStream.bufferTime = 5; // set this to whatever is comfortable..
// listen for meta data..
this.oMetaData.onMetaData = eMetaDataReceived;
this.oNetStream.client = this.oMetaData;
// attach the stream to the stage..
this.oVideo.attachNetStream(oNetStream);
this.oNetStream.play(sStreamName);
this.addChildAt(this.oVideo, 0);
trace("Connected to the RTMP server."); // debug trace..
break;
case "NetConnection.Connect.Closed":
trace("Disconnected from the RTMP server."); // debug trace..
break;
case "NetStream.Play.StreamNotFound":
trace("This stream is currently unavailable."); // debug trace..
break;
}
}
}
}
This is the actionscript3 code that is the only code i have gotten to work. But this only pulls in a single stream on a single display. I mean I could work with this and just have twelve of them. But that seems to be a waste. What is the best method to get this to work. I am very new so this next question seems even dumb to me! But cant i just create 12 flash files and import them and arrange them in a single project?
I'm an as3 newbie and I'm trying to send a message through netstream to a function that will handle it.
Here is the line that sends
public function _attachLocalVideoAndAudio(muteCam:Boolean = false, muteMic:Boolean =
false):void
{
...
_outgoingStream.send("flagVideo",true);
...
}
public function flagV():Boolean
{
var client:Object;
client.flagVideo=function(flag:Boolean):void{
check=flag;
}
return check;
}
*check is defined
I'm using Monster Debugger to debug and it seems that there is a problem with the inner function that handles the flag. There isn't much tutorials on the web on netstream.send() but I wrote this code based on something I saw online.
The Sound API seems to be missing a function to indicate that a sound is finished playing. Is there some other way of finding out if the sound is done?
Not without submitting a patch to libgdx as far as I know the underlying Sound Backends for both OpenAL and Android don't even track the information internally, though the Music API has an isPlaying() function and getPosition() function as per the documentation.
just set this
sound.setLooping(false);
this way it will not run again and again.
and to check whether sound is playing or
not do this.
make a boolean variable
boolean soundplaying;
in render method do this
if(sound.isPlaying()){
soundplaying =true
}
and make a log
gdx.app.log("","sound"+soundplaying);
You can track this by storing the sound instance id that e.g. play() and loop() return. Example code:
private Sound sound;
private Long soundId;
...
public void startSound() {
if (soundId != null) {
return;
}
soundId = sound.loop(); // or sound.play()
}
public void stopSound() {
sound.stop(soundId);
soundId = null;
}
If you didn't want to have to call stopSound() from client code, you could just call it from startSound() instead of the return, to ensure any previous sound is stopped.