I am working on a very simple player written in MXML+ActionScript whose functions are exported to be called by a simple Javascript in an HTML page.
Both codes are provided below.
For the mp3 "path" all is working perfectly for playing, pausing, resuming and stopping...
For the m4a "path", starting is working well, stopping too but pausing is bugging
After having started an m4a, when I clicked on "pause" it rightly stops the stream.
But when I am clicking back on the button to resume, it does not start again at all
Does anybody know where is the problem?
Is the fact that I'm using just a simple Apache Web Server and not a real Flash Streaming server the reason why it does not work?
Thanks in advance for your help.
The MXML+ActionScript 3
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="callBacks()">
<mx:Script>
<![CDATA[
import flash.events.Event;
import flash.media.Sound;
import flash.net.URLRequest;
import flash.external.ExternalInterface;
public var playingChannel:SoundChannel;
public var playingSound:Sound;
public var pausePosition:int=0;
public var playingUrl:String="";
public var codec:String="";
public var playingStream:NetStream;
public function playSound(url:String):void {
if (playingUrl!=url) {
if (playingUrl!="") {
stopSound();
}
playingUrl=url;
codec=playingUrl.substring(playingUrl.length-3);
if (codec=="m4a") {
var mySound:SoundTransform;
var connect_nc:NetConnection = new NetConnection();
connect_nc.connect(null);
playingStream=new NetStream(connect_nc);
playingStream.play(url);
}
else if (codec=="mp3") {
playingSound=new Sound(new URLRequest(url));
playingChannel=playingSound.play();
}
}
else {
if (codec=="m4a")
playingStream.pause();
else
playingChannel=playingSound.play(pausePosition);
}
}
public function pauseSound():void {
if (codec=="m4a")
playingStream.pause();
else if (codec=="mp3") {
pausePosition=playingChannel.position;
playingChannel.stop();
}
}
public function stopSound():void {
if (codec=="m4a")
playingStream.close();
else if (codec=="mp3") {
pausePosition=0;
playingChannel.stop();
}
playingUrl="";
}
public function callBacks():void {
ExternalInterface.addCallback("play",playSound);
ExternalInterface.addCallback("pause",pauseSound);
ExternalInterface.addCallback("stop",stopSound);
}
]]>
</mx:Script>
</mx:Application>
and the basic HTML+Javascript
<html>
<head>
<script src='jquery.js'></script>
<script>
function play() {
//alert('clicked');
var url=$("#url").val();
var k=url.substring(url.length-3);
fromFlash('testFlash').play(url);
var b=document.getElementById('pp');
b.setAttribute('src','pauseButton.jpg');
b.setAttribute('onclick','pause()');
}
function pause() {
fromFlash('testFlash').pause();
var b=document.getElementById('pp');
b.setAttribute('src','playButton.jpg');
b.setAttribute('onclick','play()');
}
function stop() {
fromFlash('testFlash').stop();
var b=document.getElementById('pp');
b.setAttribute('src','playButton.jpg');
b.setAttribute('onclick','play()');
}
function fromFlash(movieName) {
var isIE = navigator.appName.indexOf("Microsoft") != -1;
return (isIE) ? window[movieName] : document[movieName];
}
</script>
</head>
<body>
<object id="testFlash" width="0" height="0">
<param name="movie" value="player.swf"></param>
<param name="allowFullScreen" value="true"></param>
<embed name="testFlash" src="player.swf" type="application/x-shockwave-flash" allowfullscreen="true" width="0" height="0">
</embed>
</object>
<input id="url"/>
<span><img id="pp" src="playButton.jpg" onclick="play()"/></span>
<span><img src="stopButton.jpg" onclick="stop()"/></span>
</body>
</html>
I believe you want to call pause() again to resume, not play().
According to the NetStream documentation, the pause() method is used for both pause and resume.
Related
I have tried passing values using javascript like below
<script language= "javascript" type= "text/javascript">
var num;
function getVal()
{
num=document.getElementById('in').value;
alert(document.getElementById('parm').value);
}
</script>
<body>
<form >
Number : <input type="text" id="in" ><br/>
<button id="myBtn" onclick="getVal()">Try it</button><br/>
</form>
<APPLET code="Calc.class" width="100" height="100">
<PARAM name="number" id="parm">
</APPLET>
</body>
</html>
The alert box displays the entered value on screen but the applet code is not displaying the same. My applet code is
public class Calc extends Applet
{
private String strDefault = "Hello! Java Applet.";
public void paint(Graphics g) {
String strParameter = this.getParameter("number");
if (strParameter == null)
strParameter = strDefault;
g.drawString(strParameter, 10, 10);
}
}
Can anyone tell me the code to pass and retrieve values to and from param tag to html?
I think you can specify your parameters from javascript objects like so:
<applet code="Calc.class" width="100" height="100">
<param name="number" id="parm" value="&{num};">
</applet>
However, I'm not sure of the compatibility with IE so you may have to document.write out your applet code injecting the respective parameter values like so:
<head>
<script type="text/javascript">
var num;
function getVal() {
num = document.getElementById('in').value;
writeAppletTags();
}
function writeAppletTags() {
var container = document.getElementById("applet-container");
container.innerHTML = "<applet code=\"Calc.class\" width=\"100\" height=\"100\">";
container.innerHTML += "<param name=\"number\" value=\"" + num + "\">";
container.innerHTML += "</applet>";
}
</script>
</head>
<body>
Number : <input type="text" id="in" ><br/>
<button id="myBtn" onclick="getVal()">Try it</button><br/>
<div id="applet-container" />
</body>
Sending POST from Java
As I said in my comment, this is a little more complicated. You'd have to POST (you could also use GET) your values to a hosted file (can be any server side scripting technology). The following demonstrates this, code taken from here.
URL url;
URLConnection urlConnection;
DataOutputStream outStream;
DataInputStream inStream;
// Build request body
String body = "key=value";
// Create connection
url = new URL("http://myhostedurl.com/receiving-page.php");
urlConnection = url.openConnection();
((HttpURLConnection)urlConnection).setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.setRequestProperty("Content-Length", ""+ body.length());
// Create I/O streams
outStream = new DataOutputStream(urlConnection.getOutputStream());
inStream = new DataInputStream(urlConnection.getInputStream());
// Send request
outStream.writeBytes(body);
outStream.flush();
outStream.close();
// Close I/O streams
inStream.close();
outStream.close();
Source from this article
For example:
This is your applet codes:
import java.applet.*;
import java.awt.*;
public class DrawStringApplet extends Applet {
private String defaultMessage = "Hello!";
public void paint(Graphics g) {
String inputFromPage = this.getParameter("Message");
if (inputFromPage == null) inputFromPage = defaultMessage;
g.drawString(inputFromPage, 50, 25);
}
}
Then in HTML:
<HTML>
<HEAD>
<TITLE> Draw String </TITLE>
</HEAD>
<BODY>
This is the applet:<P>
<APPLET code="DrawStringApplet" width="300" height="50">
<PARAM name="Message" value="Howdy, there!">
This page will be very boring if your
browser doesn't understand Java.
</APPLET>
</BODY>
</HTML>
Notice: DrawStringApplet is you applet name; Message is a parameter sent to applet; Applet will then display: Howdy, there! as a result.
I have a simple flash socket that I use to connect to IRC servers. It has an open, close, and send method made available to JS through ExternalInterface, for opening connections, closing connections, and sending messages respectively. The socket calls IRC.io.receive in JS whenever it gets a message, which is parsed by JS into something useful.
Unfortunately, whenever any of the flash methods are called from JS, they return a "__ is not a function" error.
Here's the (watered down) AS, where IRC is the document class:
public class IRC extends MovieClip {
public static function open(url:String, port:int) {/* code */}
public static function close(port:int) {/* code */}
public static function send(port:int, message:String) {/* code */}
public function IRC() {
ExternalInterface.addCallback('send', IRC.send);
ExternalInterface.addCallback('open', IRC.open);
ExternalInterface.addCallback('close', IRC.close);
}
}
And HTML/JS:
<html>
<head>
<script type="text/javascript">
window.IRC = {
io: {}
};
IRC.io.receive = function(message) {/* code */}
IRC.io.send = function(port, str) {
document.getElementById('socket').send(port, str);
}
IRC.io.open = function(url, port) {
document.getElementById('socket').open(url, port);
}
IRC.io.close = function(port) {
document.getElementById('socket').close(port);
}
</script>
</head>
<body>
<!-- ui -->
<embed src="socket.swf" quality="high" allowscriptsaccess="always" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" allowfullscreen="false" style="display:none;">
</body>
<html>
Any call to any of the functions registered with ExternalInterface throws a "function does not exist" exception. Did I do something wrong?
Try signalling from your swf when it's ready to receive calls.
For example, in your ActionScript:
ExternalInterface.call('initIRQ');
And in your JavaScript:
function initIRQ() {
//Begin communication with swf
}
I'm using JavaScript interface for checking if Google's StreetView is available. My problem is that from android 3.0 code stopped working, and I am unnable to find why. Problem is that methods from "JavascriptCheck" interface are never called and Logcat doesn't show any errors.
Java code:
public void showStreetView(GeoPoint geoPoint) {
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JavascriptCheck(), "Android");
lat = geoPoint.getLatitudeE6()/1E6;
lon = geoPoint.getLongitudeE6()/1E6;
webView.loadDataWithBaseURL("", context.getString(R.string.html_streetview, lat, lon), "text/html", "UTF-8", "");
}
public class JavascriptCheck {
public void hasStreetview(boolean hasStreetview) {
if (hasStreetview) {
openStreetView();
} else {
Toast.makeText(context, context.getString(R.string.loc_no_street_view), Toast.LENGTH_SHORT).show();
}
}
}
WebView in layout file:
<WebView android:id="#+id/webView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:visibility="gone">
</WebView>
JavaScript string:
<string name="html_streetview">
<html>
<head>
<script src=\"http://maps.google.com/maps?file=api&v=2& sensor=false\" type=\"text/javascript\"/>
</head>
<body>
<script type=\"text/javascript\">
var testPoint = new GLatLng(%1$s, %2$s);
var svClient = new GStreetviewClient();
svClient.getNearestPanoramaLatLng(testPoint, function (nearest) {
if ((nearest !== null) && (testPoint.distanceFrom(nearest) <= 100)) {
Android.hasStreetview(true);
} else {
Android.hasStreetview(false);
}
});
</script>
</body>
</html>
</string>
Solved my problem long ago, just wanted to share with others. Honeycomb and later Android versions require that you use full html <script> tags. Also it is better to keep script string in assets folder. My assets/index.html looks like this now:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false" type="text/javascript"></script>
<script type="text/javascript">
var sv = new google.maps.StreetViewService();
function hasStreet(lat, lon) {
var point = new google.maps.LatLng(lat, lon);
sv.getPanoramaByLocation(point, 50, isSVAvailable);
}
function isSVAvailable(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
Android.hasStreetview(true);
} else {
Android.hasStreetview(false);
}
}
</script>
</head>
<body></body>
</html>
I too was using this function and have seen it broken since I tried upgrading my app for ICS. It seems that the Javascript won't execute if you have an external src link. If you take out the javascript src link and add some logging you'll see that the script will run (and obviously return false all the time).
I know in the docs they recommend not using javascript that calls into your native code unless you control all elements in the javascript but perhaps now they explicitly stop code from running that references an external resource?
I am having a hard time getting ExternalInterface to work on Firefox. I am trying to call a AS3 function from javascript. The SWF is setup with the right callbacks and it is working in IE.
I am using AC_RunActiveContent.js to embed the swf into my page. However, I have modified it to add an ID to the Object / Embed Tags. Below are object and embed tag that are generated for IE and for Firefox respectively.
<object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="400" height="400" align="middle" id="jpeg_encoder2" name="jpeg_encoder3" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" >
<param name="movie" value="/jpeg_encoder/jpeg_encoder3.swf" />
<param name="quality" value="high" />
<param name="play" value="true" />
<param name="loop" value="true" />
<param name="scale" value="showall" />
<param name="wmode" value="window" />
<param name="devicefont" value="false" />
<param name="bgcolor" value="#ffffff" />
<param name="menu" value="false" />
<param name="allowFullScreen" value="false" />
<param name="allowScriptAccess" value="always" />
</object>
<embed
width="400"
height="400"
src="/jpeg_encoder/jpeg_encoder3.swf"
quality="high"
pluginspage="http://www.macromedia.com/go/getflashplayer"
align="middle"
play="true"
loop="true"
scale="showall"
wmode="window"
devicefont="false"
id="jpeg_encoder2"
bgcolor="#ffffff"
name="jpeg_encoder3"
menu="false"
allowFullScreen="false"
allowScriptAccess="always"
type="application/x-shockwave-flash" >
</embed>
I am calling the function like this...
<script>
try {
document.getElementById('jpeg_encoder2').processImage(z);
} catch (e) { alert(e.message); }
</script>
In Firefox, I get an error saying "document.getElementById("jpeg_encoder2").processImage is not a function"
Any Ideas?
Hmm, did you expose your actionscript function to Javascript with addCallback ?
Adobe documentation on addCallback
Below is an example of how a Flash movie is placed within a html page. This movie is very simple movie with a stop action at the beginning. The movie is shown below under Test Runs subject. This particular html code was auto generated by FlashMX's Publish command. Notice that the Flash movie file is simplemovie.swf; and an id and a name have been assigned automatically by Flash to match the movie filename (minus the .swf extension). In reality, the name and id could be anything (but do not use exoteric names, especially, do not start with a number), as long as it has not been used by any other element in the same page.
`codebase="http://download.macromedia.com/pub/shockwave/cabs/flash`/swflash.cab#version=6,0,0,0"
` WIDTH="150" HEIGHT="75" id="simplemovie" ALIGN="">
` quality=medium
` swliveconnect="true"
` bgcolor=#FFFFFF WIDTH="150" HEIGHT="75"
` name="simplemovie"
` ALIGN=""
`TYPE="application/x-shockwave-flash"
` PLUGINSPAGE="http://www.macromedia.com/go/getflashplayer">
there is a play function in the flash file the following function will calls that function:
function testEval(stringToEval)
{
var movie=eval(stringToEval);
if (movie)
{
if (movie.PercentLoaded())
{
if (movie.PercentLoaded()==100)
{
movie.Play();
}
else
{
alert("movie is still loading, try again soon");
}
}
else
{
alert("movie object found-but unable to send command");
}
}
else
{
alert("movie object not found");
}
}
See this post.
You want a JS function more like this to retrieve the Flash object (rather than getElemById):
function thisMovie(movieName) {
if(navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
};
And make sure not to call this function until the document is loaded.
Try having the same id in both object and embed tags. I remember one browser is using one tag and another browser the other...don't know which one is which. I had the same issue some time ago.
I'm got around by modifying the Example Code that comes with flash. Making sure it works, then stripping it down and adapting it for my use.
In the example notice that the object tag the id set to "ExternalInterfaceExample", then the embed tag has the name parameter set to "ExternalInterfaceExample" as well. I think that might be your clue.
Good luck!
Are your swf's visible (on the page) before you try calling them? If not, read this: swf-not-initializing-until-visible
Try these two things:
First, try calling the function from Javascript like this:
var swf;
if(navigator.appName.indexOf("Microsoft") != -1) {
swf = window["jpeg_encoder2"];
} else {
swf = document["jpeg_encoder2"];
}
if(typeof(swf) == "undefined") swf = document.getElementById("jpeg_encoder2");
swf.processImage(z);
Second, I've found that ExternalInterface calls in Firefox seem to only work with embed tags, not object tags. See if you can get it to work if you just use an embed tag. (Right now, I'm not clear whether the HTML/Javascript combo you've posted will access the object or the embed element.)
If instead of using AC_RunActiveContent.js to embed your flash movie you use swfobject there is a easy build-in way of doing that.
<head>
<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
try {
swfobject.getObjectById('jpeg_encoder2').processImage(z);
} catch (e) { alert(e.message); }
</script>
</head>
If you are not using swfObject you could just copy and paste swfobject.getObjectById straight in to your code:
<script type="text/javascript">
function getObjectById(objectIdStr) {
var r = null;
var o = getElementById(objectIdStr);
if (o && o.nodeName == "OBJECT") {
if (typeof o.SetVariable != UNDEF) {
r = o;
}
else {
var n = o.getElementsByTagName(OBJECT)[0];
if (n) {
r = n;
}
}
}
return r;
getObjectById('jpeg_encoder2').processImage(z); //call your method
</script>
Suppose the swf file is embeded into the page with the following code:
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" id="myFlash" width="600" height="500">
<param name="movie" value="myMovie.swf">
<embed type="application/x-shockwave-flash" src="myMovie.swf" name="myFlash" width="600" height="500" >
</embed>
</object>
What are the ways to get a reference to the movie with the help of JavaScript?
function getMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
}
var flash = getMovie('myFlash')
Does...
var myReference = document.getElementById("myFlash");
... suit your needs? What do you aim to do with this reference once you are done?
This is the shortest answer I can write:
var swf = this["mySWF"];
It's easy, but you need to be weary of Internet Explorer
var myFlash = $.browser.msie ? window[ 'myFlash' ] : document[ 'myFlash' ];