recreating the old youtube mobile player whit flash - html

i have an old "smartphone", since youtube killed the old flash player (html5 video doesn't work and it has so few ram that i can't even load the full "the old net"
i never worked whit flash before (and i never really did anything similar)
the basic idea is to make an host a simple html page that ask you the id of the video, it download it, downscale it to 144p, convert in flash and send it to the phone
the problem is, i don't know how to use the buffering, so it work whit short videos, but when they're too long it fail to buffer everything when loading the page and break
i would like something like how youtube work (load piece by piece)
any ideas on how should i do this?
btw, the old phone is a samsung GT-S5260 whit samsung dolfin 2.0

Ok, my AS3 is kinda rusty already, but I think it should work as the following.
First, you pass the video URL to the Flash application via FlashVars, it is a special HTML tag.
If you form HTML tags outright (figure urls and dimensions on your own):
<object width="640" height="480" type="application/x-shockwave-flash" id="X" name="X" data="flvplayer.swf" >
<param name="movie" value="flvplayer.swf">
<param name="allowScriptAccess" value="sameDomain" />
<param name="allowFullScreen" value="true" />
<param name="quality" value="high" />
<param name="wmode" value="opaque">
<param name="FlashVars" value="flvurl=movieurl.flv" />
<embed width="640" height="480" type="application/x-shockwave-flash" id="X" name="X" src="flvplayer.swf"
allowScriptAccess="sameDomain"
allowFullScreen="true"
quality="high"
flashVars="flvurl=movieurl.flv"
pluginspage="http://www.adobe.com/go/getflashplayer"
></embed>
</object>
Alternately, if you activate the Flash application through the SWFObject:
<script type="text/javascript">
var flashvars = {
"flvurl=movieurl.flv"
};
var params = {
allowScriptAccess: "sameDomain",
allowFullScreen: "true",
wmode: "opaque",
quality: "high",
menu: "false"
};
var attributes = {};
swfobject.embedSWF("flvplayer.swf", "X", "640", "480", "9.0.0","expressInstall.swf", flashvars, params, attributes);
</script>
Ok. Next step, you need the means to build that flvplayback.swf. In order to do so, you need either AIR SDK or Flex SDK (optionally FlashDevelop tool because it made things so much easier back then, auto-downloaded SDKs too, but I have no idea if it works these days) or Flash/Animate IDE. I believe it is still possible to find some kind of tutorial like "build my first Flash project".
Then, the very application in question is rather simple one. The one below goes in a form of a single class, which should be the main class if you build thru AIR/Flex SDK or assigned as the document class if it is Flash/Animate.
package
{
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.media.Video;
import flash.events.Event;
import flash.display.Sprite;
public class Main extends Sprite
{
private var playback:Video;
public function Main()
{
// Being able to access the stage is important.
if (stage) onStage(null);
else addEventListener(Event.ADDED_TO_STAGE, onStage);
}
private function onStage(e:Event):void
{
// The fact we are here means the stage is present and available.
removeEventListener(Event.ADDED_TO_STAGE, onStage);
// Obtain the video URL.
// That's why being able to access the stage was important.
var flvurl:String = stage.loaderInfo.parameters["flvurl"];
// If there's no URL provided, just stop.
// Normally I'd put some visual alert here.
if (!flvurl) return;
// Set up stage a bit.
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.stageFocusRect = false;
stage.showDefaultContextMenu = false;
// Build and start the video player.
var NC:NetConnection;
var NS:NetStream;
NC = new NetConnection;
NC.connect(null);
NS = new NetStream(NC);
NS.play(flvurl);
flvplayback = new Video;
flvplayback.attachNetStream(NS);
// Make it the size of the stage right away
// then subscribe to any size changes.
onResize(null);
stage.addEventListener(Event.RESIZE, onResize);
// Finally, attach the video player to the display list.
addChild(flvplayback);
}
private function onResize(e:Event):void
{
flvplayback.width = stage.stageWidth;
flvplayback.height = stage.stageHeight;
}
}
}
I cannot promise this would work right away, although I think it probably will. The idea is correct, the logic is straight, I just might forgot something or made some typos.

Related

AS3 - Pass variable data from HTML page into flash

I have a music player as a SWF file and I need help converting my static AS3 source paths:
var url :URLRequest = new URLRequest("images/logo.jpg");
var req:URLRequest = new URLRequest("click.mp3");
...into parameters that can be passed in from the HTML page. I'd like to do something like this:
<object width="480" height="270" data="soundplayer.swf" sound="click.mp3" image="logo.jpg"></object>`
The end result I am looking for is to specify the sound and image path within the HTML code instead of it being hard coded within my SWF file.
You can accomplish this with FlashVars
You add a <param> node in your object tag with a name of FlashVars and the value should be url encoded querystring variables.
So your scenario, this would be the start of your object tag:
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="270">
<param name="movie" value="soundplayer.swf" />
<param name="FlashVars" value="sound=click.mp3&image=logo.jpg" />
Then in AS3, you access them as follows:
var flashVars:Object = LoaderInfo(this.root.loaderInfo).parameters;
var url:URLRequest = new URLRequest("images/" + flashVars.image);
var req:URLRequest = new URLRequest(flashVars.sound);

Flash content not go full screen

I have found this but it is supposed to work as swf in the desktop, not in the html.
I am trying to make the content full screen via both at the beginning of the code and mouse event. However stage.displayState returns null. Here is how I do things;
at the beginning:
stage.displayStatus = StageDisplayState.FULL_SCREEN_INTERACTIVE;
and then
fullScreenButton.addEventListener(MouseEvent.CLICK, DoFullScreen);
function DoFullScreen(e:MouseEvent)
{
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
}
and in the function, stage.displayState traced null as I said before.
You need to target FP 11.3+ for StageDisplayState.FULL_SCREEN_INTERACTION
for below versions : StageDisplayState.FULL_SCREEN
and you have to add that flash param in your html
<param name="allowFullScreen" value="true" />
I added the sample swf and fla

Mission : Create a connection with a list of videos and a canvas make them plays 1 by 1, without stops, no click function, ended AddEventListener

I would like to make a video playlist, (Source video is copied in a canvas to block controls,
options like download video), i made 2 Drag and Drop lists and i would like to connect 1 drag n Drop list to the canvas (that is also the video player box) then play the videos 1 by 1,
witout stops, no click function, function AddEventListener ended in the canvas box.
I worth for 2 videos, here is some parts of the code :
<script type="text/javascript">
// listener function changes src
function myNewSrc() {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = "videos/80s_Mix_II-700.mp4";
myVideo.src = "videos/80s_Mix_II-700.webm";
myVideo.load();
myVideo.play();
}
// add a listener function to the ended event
function myAddListener() {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.addEventListener('ended', myNewSrc, false);
}
</script>
<body onload="myAddListener()">
<div id="video_player_box">
<video id="video" autoplay autobuffer width="1" height="1" >
<source src="videos/milenio_6_minimix_700.mp4" type="video/mp4">
<source src="videos/milenio_6_minimix_700.webm" type="video/webm">
<source src="videos/milenio_6_minimix_700.ogg" type="video/ogg">
</video>
<div align="center">
<canvas id="myCanvas" width="1130" height="560">
Your browser does not support the HTML5 canvas tag.</canvas>
</div>
<script>
var v = document.getElementById("video");
var c = document.getElementById("myCanvas");
ctx = c.getContext('2d');
v.addEventListener('play', function() {
var i = window.setInterval(function()
{
ctx.drawImage(v, 5, 5, 1130, 560)
}, 20);
}, false);
v.addEventListener('pause', function() {
window.clearInterval(i);
}, false);
v.addEventListener('ended', function() {
clearInterval(i);
}, false);
</script>
</div>
<div id="cadre2" ondrop="drop(event)" ondragover="allowDrop(event)"> <p> Canal VIP </p>
<ol><li> <video src="videos/milenio_6_minimix_700.mp4" draggable="true"
ondragstart="drag(event)" id="drag1" width="288" height="188" alt="Video 1">
</video></li>
...
The idea is to say get the videos from #cadre2, play them, 1 by 1, in the canvas until the end and loop, make the same path.
I made my list Drag and drop to have the decision to modify online the video playlist, more flexible.
Hope to have some advises!! I'm not pro of Php and dynamic, i've started Javascript but
it takes time to be pro!
If you have some code, it will be really appreciated!! Thanks in advance!!!
In order to make a player that can play videos continously you need to implement some sort of double-buffering at load level (I'll demonstrate later).
But there are some issues in the code as it is -
myVideo.src = "videos/80s_Mix_II-700.mp4";
myVideo.src = "videos/80s_Mix_II-700.webm";
myVideo.load();
This will simply override the source property. And setting the source will automatically start loading the video.
The proper way to check for video support is using the method canPlayType like this:
/// which format can we play?
if (video.canPlayType("video/mp4").length > 0) {
video.src = urlToMP4;
} else if (video.canPlayType("video/webm").length > 0) {
video.src = urlToWEBM;
} else {
video.src = urlToOggOrSomeOtherSupportedFormat;
}
The problem though with canPlayType is that it returns maybe in Chrome and probably in Firefox. It returns an empty string if it cannot play the video type so we check if string contains anything to determine the possibility for this format to play.
You also need to implement an event listener for canplay which tells your app that the video was loaded and buffered successfully and can now be started using play (or starts if autoplay was set to true).
I would recommend a simple procedure like this:
Create an array of objects with the video URLs you want to play for the various formats
When first video is loaded (canplay) start loading the next video in the list when start playing the first
I would also recommend a re-factoring of the code to handle loading and playing.
For example, if we initialize an array to hold our custom video objects:
var list = [];
we can now add URLs like this:
function addVideo(urlMP4, url) {
list.push({
urlMP4: urlMP4,
url: url,
isReady: false
})
}
Then this function will let us add a MP4 and a link for WEBM or OGG:
addVideo('http://video1.mp4', 'http://video1.webm');
addVideo('http://video2.mp4', 'http://video2.webm');
addVideo('http://video3.mp4', 'http://video3.ogg');
...
Then we need to start a "chain-reaction" so to speak by using a double-buffered loading mechanism. The first time we need to trigger it manually:
getVideo(list[0], play);
function getVideo(vid, callback) {
/// which video is playing? (see demo for details)
var video = (isVideo1 === false ? video1 : video2),
me = this;
/// we need to know when video is ready
video.addEventListener('canplay', canPlay, false);;
/// call this when ready
function canPlay(e) {
/// remove event listener (in case setting new src does not trigger)
video.removeEventListener('canplay', canPlay, false);
/// update our object with useful data, for example:
vid.isReady = true;
/// if we provided a callback then call that with custom video object
if (typeof callback === 'function')
callback(vid);
}
/// check video format support (see demo for details)
if (video.canPlayType("video/mp4").length > 0) {
video.src = vid.urlMP4;
} else {
video.src = vid.url;
}
}
Our play function will manage which video is playing and what to play next:
function play(){
/// what video is currently not playing?
var video = (isVideo1 === false ? video1 : video2),
next = current; /// current is index for list, starts at 0
/// switch
isVideo1 = !isVideo1;
/// increment for next video to platy and start over if list ended
next++;
if (next > list.length - 1) next = 0;
/// only attempt next if there are more videos than 1 in list
if (list.length > 0) getVideo(list[next]);
/// start already loaded video (getVideo)
video.play();
isPlaying = true;
/// set current to next in list
current = next;
}
Here is an online demo
I made this demo just to demonstrate the double-buffered loading. Feel free to incorporate in your own project with pause, stop etc.
There is room to move things around in the code I provided here but it's as said just example of the principle. You also need to consider a scenario where next video takes longer to load then what current video playing takes to play (ie. current video ends before next has finished loading). This is not checked in this code.
In order to properly synchronize video frames with canvas you need to use requestAnimationFrame or you will get freezes from time to time.
In the demo the loop runs all the time. You can consider to implement a conditional to stop the loop. I just implemented a conditional for drawing when video list has started playing (rAF does not use much resources in it self and you may get problems synchronizing stop and start when you switch videos so I would personally leave it running as-is for this type of scenarios (continuous video play) and only stop it if there is an error occurring).

How to stop Camera capture in as3, flex?

I'm starting work on flex using flashbuilder and I was testing cameras. Now I can get a camera to display but when I try using the stop button to stop the camera from capturing, ti doesn't work this is what I tried.
var video:Video;
public function startCamera(muteCam:Boolean=false):void{
video = new Video(); // this will work after the import is done
var camera:Camera=Camera.getCamera();
if(muteCam){
video.attachCamera(camera);
vidHolder.addChild(video);
}else{
video.attachCamera(null);
if(contains(video))
vidHolder.removeChild(video);
//camera=null;
}
}
These are my components
<s:Button x="116" y="28" label="Start" click="startCamera(true)"/>
<s:VideoDisplay id="vidHolder" x="31" y="87" width="200" height="300"
/>
<s:Button id="stop" x="208" y="28" label="Stop" click="startCamera(false)"/>
You are creating a new Video object every single time you call startCamera. So you are trying to remove a video which isn't actually on the stage.
Instead of:
video = new Video();
Use this:
if ( !video ) {
video = new Video();
}
That will only create the Video object if it has not already been created (!object evaluates the object to see if it is null or a boolean set to false. object == null would evaluate the same way in this case)

Away3D Context3D not available

I'm checking out Flash's 3D capabilities with Away3D, and I'm following the tutorial here. I've run into a major problem though. Everytime I run my project in the browser, I get this error:
Error #2044: Unhandled ErrorEvent:. text=Error #3702: Context3D not available.
I can't see where this error comes from, but it happens after my constructor function ends and before the ENTER_FRAME handler starts.
My code is like this:
package {
import away3d.containers.View3D;
import away3d.entities.Mesh;
import away3d.materials.ColorMaterial;
import away3d.primitives.SphereGeometry;
import flash.display.Sprite;
import flash.events.Event;
[SWF(backgroundColor="#000000", frameRate="60", width="1024", height="768")]
public class TestAway extends Sprite {
private var view:View3D;
public function TestAway() {
view=new View3D();
addChild(view);
var sphereGeometry:SphereGeometry=new SphereGeometry(350);
var sphereMaterial:ColorMaterial=new ColorMaterial(0xff0000);
var mesh:Mesh=new Mesh(sphereGeometry, sphereMaterial);
view.scene.addChild(mesh);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void {
view.render();
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
}
}
Now the wierd thing is, when I run it on my browser (FP 11.2), it doesn't work (gives that error), but I can run the swf from the desktop perfectly.
Also, the example file on the tutorial page runs perfectly. What setting is missing, and how can I fix it?
Well, it appears you need to set wmode as direct to make use of the 3D API.
While I had seen this bit of info, the html wrapper needs to be modified in 3 places for it to work on all configurations:
(1) In the javascript for swfObject
params.wmode = "direct";
(2) In the <object> tag
<param name="wmode" value="direct" />
and (3) in the <object> tag for IE
<param name="wmode" value="direct" />
To extend further helpful hints, if you are trying to open an application that uses Context3D in a new NativeWindow, you need to make sure that the you specify the renderMode in the NativeWindowInitOptions that gets passed into the NativeWindow. The render mode cannot change after the Native Window gets created.
// New window.
options = new NativeWindowInitOptions();
options.renderMode = "direct";
options.transparent = true;
options.systemChrome = NativeWindowSystemChrome.NONE;
nativeWindow = new NativeWindow( options );
I'm posting here hoping to help anyone with the same problem, but exporting to AIR.
Edit the app descriptor.xml and change the value to of rendermode to:
<renderMode>direct</renderMode>
Hope it helps