I tried to make an image/sound gallery with PhoneGap media plugin, but I ran into one problem. When I click on a picture, the sound plays, but when I click on another one it plays that one too. Any idea how I can let them play one sound at a time?
<script type="text/javascript" charset="utf-8">
// Audio player
//
var my_media = null;
var mediaTimer = null;
// Play audio
//
function playAudio(src) {
// Create Media object from src
my_media = new Media(src, onSuccess, onError);
// Play audio
my_media.play();
// Update my_media position every second
if (mediaTimer == null) {
mediaTimer = setInterval(function() {
// get my_media position
my_media.getCurrentPosition(
// success callback
function(position) {
if (position > -1) {
setAudioPosition((position) + " sec");
}
},
// error callback
function(e) {
console.log("Error getting pos=" + e);
setAudioPosition("Error: " + e);
}
);
}, 1000);
}
}
// Pause audio
//
function pauseAudio() {
if (my_media) {
my_media.pause();
}
}
// Stop audio
//
function stopAudio() {
if (my_media) {
my_media.stop();
}
clearInterval(mediaTimer);
mediaTimer = null;
}
// onSuccess Callback
//
function onSuccess() {
console.log("playAudio():Audio Success");
}
// onError Callback
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
// Set audio position
//
function setAudioPosition(position) {
document.getElementById('audio_position').innerHTML = position;
}
</script>
<img src="arMonika/audio.png" width="147" height="147" />
<img src="arMonika/k.tech.spec.png" width="141" height="141" />
For those who have the same issue :
When you start defining your player , player or "Media" stores in variable , in your case it is "my_media" .
To solve this problem just define your variable "my_media" as a global var.
and then for each link that should play sound you need to stop your previos media and store new media in that variable like this :
my_media.stop
new Media(src, onSuccess, onError);
just becareful about defining its variable as a GLOBAL variable.
Hoped it helps.
Related
I have javascript code as follows..by which when a client clicks on call button a signal is send to another client and a sound is played at other client till he accepts call. The button turns to End call after clicking Call button:
function beginCall(obj) {
console.log(obj.value);
obj.setAttribute("onclick", "endCall(this,'" + obj.value + "')");
obj.value = 'End Call';
_stream = _streams[obj.id.replace("btn_", "")];
var streamNames = _stream.name.toString();
session.signal({
type: "begincall",
to: _stream.connection,
data: { streamId: _selfstream.streamId + "|" + _selfstream.name }
}, function (error) {
if (error) {
console.log("signal error: " + error.reason);
} else {
console.log("signal sent: begincall:");
}
});
}
function signalEventHandler(event) {
if (event.type == "signal:begincall") {
//sound alert
var audio = new Audio('inc/sound.mp3');
audio.loop = true;
audio.play();
}
}
The issue is that after clicking on call button and if the same client clicks on end call button again and again before the other person accepts the call, multiple audio gets played as loop.
I need to make the audio play only once based on
if (event.type == "signal:begincall") {
How is that possible?
Trying to play audio files from the external storage of phone.
Went through this plugin first finding the URI for a particular mp3 file. Then passed that to the cordova-plugin-media instance.
// find music file URI from the sdcard
new ExternalStorageSdcardAccess( fileHandler ).scanPath( "file:///storage/C67A-18F7/Music/" );
function fileHandler( fileEntry ) {
// console.log( fileEntry.name + " | " + fileEntry.toURL() );
}
// create a button instance
let mbutton = new Button({
centerX: 0, top: [fbutton,100],
text: 'play music'
}).appendTo(ui.contentView);
// call the play media function from the button
mbutton.on('select', () => {
// load and play the music:
playAudio("file:///storage/C67A-18F7/Music/demo/testSound.mp3")
});
function playAudio(url) {
// Play the audio file at url
var my_media = new Media(url,
// success callback
function () {
console.log("playAudio():Audio Success");
},
// error callback
function (err) {
console.log("playAudio():Audio Error: " + err.code + err.message);
},
// status callback
function (status) {
console.log("playAudio():Audio Status: " + status);
}
);
// Play audio
my_media.play();
my_media.setVolume('1.0');
}
I checked the adb for log. This is what I got specifically hitting those buttons - http://paste.ubuntu.com/25767292/
incoming-operation: 'Call' on 'cordova.plugin' (o13) with method 'exec' with properties {action=create, arguments=["d39113d0-b5f5-bf2d-8a84-5afbbc6ae9a0","file:///storage/C67A-18F7/Music/demo/testSound.mp3"], callbackId=Media975330222}
incoming-operation: 'Call' on 'cordova.plugin' (o13) with method 'exec' with properties {action=startPlayingAudio, arguments=["d39113d0-b5f5-bf2d-8a84-5afbbc6ae9a0","file:///storage/C67A-18F7/Music/demo/testSound.mp3",null], callbackId=INVALID}
outgoing-operation: 'Notify' o13 of 'finish' with arguments {message=S01 Media975330222 s, status=1, keepCallback=false, callbackId=Media975330222}
ExtMediaPlayer-JNI: env->IsInstanceOf fails
MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
ExtMediaPlayer-JNI: env->IsInstanceOf fails
MediaPlayer-JNI: JNIMediaPlayerFactory: bIsQCMediaPlayerPresent 0
I am using Capacitor with an ionic react project and was able to get cordova-plugin-media playing local files by using it in conjunction with cordova-plugin-file. I am the ionic-native wrappers, but I think its the same code here.
NOTE: iOS requires you to remove 'file://' and Android does not.
const finishedFilePath = `${File.applicationDirectory}public/assets/audio/file.mp3`;
const hybridTransitionAudioFile = Media.create(isPlatform('ios') ? transitionFilePath.replace('file://', '') : transitionFilePath);
hybridTransitionAudioFile.play();
1- install this
https://play.google.com/store/apps/details?id=com.adobe.phonegap.app&hl=en
2- install this
http://docs.phonegap.com/getting-started/1-install-phonegap/desktop/
3- connect your laptop and your phone on same network
4- follow the getting started on this and run it on your phone , i suppose you wont get the same error , because im my case it dose not work in browser nor emulator in case of phone gap
Reference:
https://phonegap.com/getstarted/
give feed back so i can update my answer here
HTML PART
for audio src
<audio id="successSound" src="/android_asset/www/audio/correct.mp3" type="audio/mpeg"></audio>
<audio id="errorSound" src="/android_asset/www/audio/error.mp3" type="audio/mpeg" ></audio>
</body>
</html>
Example of my version that works i hope there is help in it
playAudio("errorSound");
var my_media = null;
var mediaTimer = null;
function playAudio(id) {
var audioElement = document.getElementById(id);
var src = audioElement.getAttribute('src');
// Create Media object from src
my_media = new Media(src, onSuccess, onError);
// Play audio
my_media.play();
// Update my_media position every second
if (mediaTimer == null) {
mediaTimer = setInterval(function() {
// get my_media position
my_media.getCurrentPosition(
// success callback
function(position) {
if (position > -1) {
setAudioPosition((position) + " sec");
}
},
// error callback
function(e) {
console.log("Error getting pos=" + e);
setAudioPosition("Error: " + e);
}
);
}, 1000);
}
}
function setAudioPosition(position) {
document.getElementById('audio_position').innerHTML = position;
}
// onSuccess Callback
//
function onSuccess() {
}
// onError Callback
function onError(error) {
switch(error.code){
case MediaError.MEDIA_ERR_ABORTED:
alert('MEDIA_ERR_ABORTED code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NETWORK:
alert('MEDIA_ERR_NETWORK code: ' + error.code);
break;
case MediaError.MEDIA_ERR_DECODE:
alert('MEDIA_ERR_DECODE code: ' + error.code);
break;
case MediaError.MEDIA_ERR_NONE_SUPPORTED:
alert('MEDIA_ERR_NONE_SUPPORTED code: ' + error.code);
break;
}
}
I am clicking on my image to call the playAudio(). I am using phonegap to do this.
Here is my function
<script type="text/javascript" charset="utf-8">
// Audio player
//
var my_media = null;
// Play audio
//
function playAudio(src) {
if (my_media == null) {
// Create Media object from src
my_media = new Media(src, onSuccess, onError);
} // else play current audio
// Play audio
my_media.play();
}
// onSuccess Callback
//
function onSuccess() {
console.log("playAudio():Audio Success");
}
// onError Callback
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
</script>
Here is my image
<input type="image" id="myimage" src="numb/equal.png" style="height:100px;width:100px;margin-top:0px" onclick="playAudio('/android_asset/www/Mobile/sound/'+ abc +'.mp3');"/>
On clicking this image it should play the corresponding mp3. But in my console I am getting "Media is not Defined"
Here is the screenshot of the error
How can i fix this ?
If you are using Phoengap/Cordova, you shouldn't include /android_asset/www/ in the path to the mp3. You can think of that /android_asset/www/ folder as the 'context root' - all relative URLs will automatically have this appended to them.
So just change onclick="playAudio('/android_asset/www/Mobile/sound/'+ abc +'.mp3');" to
onclick="playAudio('./Mobile/sound/'+ abc +'.mp3');" and it should find the correct path to your audio.
I wouldnt do it this way. With HTML5 you can play audio files very easily with the AUDIO TAG. Make your javascript create the element that is described and set the autoplay property.
I am trying to play list of video files stored in a folder one by one but if any of the file is missing or deleted the program will stop but i want it jump to the next video and continue its execution is there any way to catch this error and jump to the next one?
function advanceVideo()
{
video_count++;
if (video_count > num_files) video_count = 1;
videoPlayer.setAttribute("src","video/video"+video_count+".ogg");
video.load();
video.play();
}
I am using the above function for accessing the video file in the folder.
Make use of the various events the <video /> element offers
// function to load the next video (without .play())
function advanceVideo() {
video_count = (video_count + 1) % num_files;
this.setAttribute("src", "video/video" + video_count + ".ogg");
this.load();
}
// if the current video has reached the end, load the next
videoPlayer.addEventListener("ended", advanceVideo);
// if the browser fetched enough data to play the video start playing
videoPlayer.addEventListener("canplay", function() {
this.play();
});
// if an error occured load the next video
videoPlayer.addEventListener("error", advanceVideo);
Update
This should do what you've requested in your comment
var num_files = 2,
playedVideos = 0;
// load next video
function advanceVideo() {
// current video id or -1 if not found
var curId = parseInt((/video(\d+)\.ogg$/.exec(this.src) || [, -1])[1], 10);
// reset if all videos have been played
if (playedVideos == num_files) {
playedVideos = 0;
curId = -1;
}
this.src = "video/video" + (curId + 1) + ".ogg";
this.load();
}
// if the current video has reached the end, load the next
videoPlayer.addEventListener("ended", function() {
playedVideos++;
advanceVideo();
});
// if the browser fetched enough data to play the video start playing
videoPlayer.addEventListener("canplay", function() {
this.play();
});
// if an error occured load the next video
videoPlayer.addEventListener("error", advanceVideo);
If there are less videos to play than num_files indicates, this will end in an "infinite loop" as it will try all videos until curId reaches the value Infinity!
Try using try-catch block:
function advanceVideo()
{
video_count++;
if (video_count > num_files) video_count = 1;
videoPlayer.setAttribute("src","video/video"+video_count+".ogg");
try {
video.load();
video.play();
} catch (e) { }
}
I'm trying to write an Android app with PhoneGap that contains multiple HTML files. In every HTML I would like to include an mp3 file that the user can play and stop. This has worked so far. The problem that I encounter is when trying to put multiple mp3 files in one file.
The thing that I would like to achieve is to put the general audio player javescript in one file and to tell in the HTML which file should be played. Is this possible and how? Thanks!
My code for one of the html files looks like this:
<script type="text/javascript" charset="utf-8" src="phonegap.js"></script>
<script type="text/javascript" charset="utf-8">
//-------------------------------------------------------------------------
// Audio player
//-------------------------------------------------------------------------
var media1 = null;
var media1Timer = null;
var audioSrc = null;
/**
* Play audio
*/
function playAudio(url) {
console.log("playAudio()");
console.log(" -- media="+media1);
//var src = "/android_asset/www/audio/01.mp3";
var src = "/android_asset/www/audio/01.mp3";
if (url) {
src = url;
}
// Stop playing if src is different from currently playing source
if (src != audioSrc) {
if (media1 != null) {
stopAudio();
media1 = null;
}
}
if (media1 == null) {
media1 = new Media(src,
function() {
console.log("playAudio():Audio Success");
},
function(err) {
console.log("playAudio():Audio Error: "+err);
setAudioStatus("Error: " + err);
},
function(status) {
console.log("playAudio():Audio Status: "+status);
setAudioStatus(Media.MEDIA_MSG[status]);
// If stopped, then stop getting current position
if (Media.MEDIA_STOPPED == status) {
clearInterval(media1Timer);
media1Timer = null;
}
});
}
audioSrc = src;
// Play audio
media1.play();
if (media1Timer == null) {
media1Timer = setInterval(
function() {
media1.getCurrentPosition(
function(position) {
console.log("Pos="+position);
if (position > -1) {
setAudioPosition((position/1000)+" sec");
}
},
function(e) {
console.log("Error getting pos="+e);
setAudioPosition("Error: "+e);
}
);
},
1000
);
}
// Get duration
var counter = 0;
var timerDur = setInterval(
function() {
counter = counter + 100;
if (counter > 2000) {
clearInterval(timerDur);
}
var dur = media1.getDuration();
if (dur > 0) {
clearInterval(timerDur);
document.getElementById('audio_duration').innerHTML = (dur/1000) + " sec";
}
}, 100);
}
/**
* Pause audio playback
*/
function pauseAudio() {
console.log("pauseAudio()");
if (media1) {
media1.pause();
}
}
/**
* Stop audio
*/
function stopAudio() {
console.log("stopAudio()");
if (media1) {
media1.stop();
}
clearInterval(media1Timer);
media1Timer = null;
}
/**
* Set audio status
*/
var setAudioStatus = function(status) {
document.getElementById('audio_status').innerHTML = status;
};
/**
* Set audio position
*/
var setAudioPosition = function(position) {
document.getElementById('audio_position').innerHTML = position;
};
</script>
</head>
<body>
<!-- Audio -->
<div id="info">
<h2>Audio</h2>
</div>
Play
Pause
Stop
</body>
You might consider using a page with a frame on it. Place your common javascript in the of the main page and then call back to parent.playAudio(src) to kick off the player from each sub-page as it's loaded into the frame.
Another possible direction is use of jqMobile. By default, jqMobile loads pages using Ajax calls..consequently, your javascript can be loaded by the very first page only...and all subsequent page loads via ajax do not totally replace the DOM...leaving your javascript in tact. I have developed a small app using phonegap and jqMobile with fairly good success.