I am using Monaca.mobi to build a hybrid app. When I build the app for IOS everything is fine; however, when I build it for an android device (Nexus 7) audio does come through. In the Monaca debugger; however, the audio works fine. Is there something about android devices that I am not aware about, maybe some permissions of the app?
Sound is played through an angularJS function called on certain button clicks. I know that this code is correct, just thought I might share it:
function DontAsk($scope){
$scope.play = function(){
var audio = new Audio();
audio.src = 'sounds/DontEventAsk.mp3';
audio.play();
}}
Thanks for any insight.
your above code is only working with iOS. For Android, the path to your local audio file is not recognized. The following code will work for both OSes. I've already tested with the built app too.
$scope.play= function(){
var os = navigator.platform;
if (os=='iPhone'){
var url = "sounds/DontEventAsk.mp3";
}
else{
var url = getPhoneGapPath() + "sounds/DontEventAsk.mp3";
}
var my_media = new Media(url,
// success callback
function() {
console.log("playAudio():Audio Success");
},
// error callback
function(err) {
console.log("playAudio():Audio Error: "+JSON.stringify(err));
});
// Play audio
my_media.play();
}
The big question here is what browser does the Monaca.mobi app use internally? The default Android browser is notorious for not supporting newer codecs like Audio that require HTML5. You might be better off setting some kind of flag that the app can watch and then use the app to play the sound instead of relying on the browser.
Related
I'm building an app in Ionic that needs to be able to play 2 audio files at the same time.
At first I tried to use the HTML5 Audio capabilities which allowed me to do that. However: on the web it played two sounds concurrently as desired but when running on my Android phone only 1 audio file gets played.
I looked further and found ngCordova's $cordovaMedia.
So I went ahead and used the info on ngCordova's website: http://ngcordova.com/docs/plugins/media/
(and I included the js files)
Resulting in the following code:
angular.module('starter.controllers', ['ngCordova'])
.controller('HomeCtrl', function($scope, $cordovaMedia, $ionicLoading) {
$scope.play = function() {
var media = $cordovaMedia.newMedia('http://www.tonycuffe.com/mp3/tail%20toddle.mp3');
media.play();
var media2 = $cordovaMedia.newMedia('http://www.tonycuffe.com/mp3/saewill.mp3');
media2.play();
console.log(media);
console.log(media2);
}
});
Both objects play fine seperate, but when played together only media2 is heard.
Anyone knows why this is and if I can fix it? I'm surely open to alternatives as well.
A simple usage of the Web Audio API:
var UnprefixedAudioContext = window.AudioContext || window.webkitAudioContext;
var context;
var volumeNode;
var soundBuffer;
context = new UnprefixedAudioContext();
volumeNode = context.createGain();
volumeNode.connect(context.destination);
volumeNode.gain.value = 1;
context.decodeAudioData(base64ToArrayBuffer(getTapWarm()), function (decodedAudioData) {
soundBuffer = decodedAudioData;
});
function play(buffer) {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(volumeNode);
(source.start || source.noteOn).call(source, 0);
};
function playClick() {
play(soundBuffer);
}
inside a UIWebView works fine (plays the sound); but when you switch to the Music app and play a song, and then come back to the app with the UIWebView the song stops playing.
The same code inside Safari doesn't have this problem.
Is there a workaround to avoid this behavior?
Here's the full fiddle:
http://jsfiddle.net/gabrielmaldi/4Lvdyhpx/
Are you on iOS? This sounds like an audio session category issue to me. iOS apps define how their audio interacts with audio. From Apple's documentation:
Each audio session category specifies a particular pattern of “yes”
and “no” for each of the following behaviors, as detailed in Table
B-1:
Interrupts non-mixable apps audio: If yes, non-mixable apps will be
interrupted when your app activates its audio session.
Silenced by the Silent switch: If yes, your audio is silenced when the
user moves the Silent switch to silent. (On iPhone, this switch is
called the Ring/Silent switch.)
Supports audio input: If yes, app audio input (recording), is allowed.
Supports audio output: If yes, app audio output (playback), is
allowed.
Looks like the default category silences audio from other apps:
AVAudioSessionCategorySoloAmbient—(Default) Playback only. Silences
audio when the user switches the Ring/Silent switch to the “silent”
position and when the screen locks. This category differs from the
AVAudioSessionCategoryAmbient category only in that it interrupts
other audio.
The key here is in the last sentence: "it interrupts other audio".
There are a number of other categories you can use depending on whether or not you want your audio silenced when the screen is locked, etc. AVAudioSessionCategoryAmbient does not silence audio.
Give this a try in the objective-c portion of your app:
NSError *setCategoryError = nil;
BOOL success = [[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryAmbient
error: &setCategoryError];
if (!success) { /* handle the error in setCategoryError */ }
I'm developing a firefox extension, and I'd like it to play a notification sound when an event occurs. However, despite following the instructions from Play audio from firefox extension's data directory, the sound doesn't play. It's stored in my data directory. Here is my code:
var pageworker = require ("sdk/page-worker");
let { setTimeout } = require("sdk/timers"); //setTimeout is not enabled by default in ff extensions
function playSound(sound){
console.log("playing sound: "+sound);
var soundPlayer = pageworker.Page({
contentURL: data.url("blank.html"),
contentScript: "new Audio('notification-1.mp3').play();console.log('the audio did run')",//This is where it should play, but it doesn't, even if I remove the console.log
//The script does work if I type it into the javascript console, but replace the file name with a file:/// URL
});
setTimeout(function(){soundPlayer.destroy();},5000);//destroy the sound player after 5 seconds
}
but although both console.log's are called, no audio ever plays.
This is both in the XPI and when using cfx.
As noted in the comments, try using an absolute URL in the contentScript string:
"new Audio("+data.url("notification-1.mp3")+").play();"
I have created an app using JavaScript, HTML, CSS and Cordova 2.9.0 which outputs a sound when objects are dragged on the screen. It works fine on iOS, but I am struggling to get the sound to output in the emulator.
I have looked at many other posts and the Android documentation, it says to use the MediaPlayer to output audio files. I am not using Java though so cant use the code they have shown.
Does anyone know how to run the MediaPlayer through JavaScript to play the audio files?
Here is what I have so far (works in Chrome and on iOS):
$(function() {
$(".cards img").draggable({
start: function(event, ui) {
if(window.HTMLAudioElement) {
console.log(ui.helper.context.id);
var id = ui.helper.context.id;
console.log("playing sound ", id);
var soundFile = '../assets/audio/' + id + ".mp3";
var snd = new Media(soundFile);
snd.play();
event.stopPropagation();
}
}
});
});
Here are the errors that get output when I drag the images:
I found a solution here.
For some reason var soundFile = '../assets/audio/' + id + ".mp3"; doesn't work and var soundFile = '/android_asset/www/assets/audio/' + id + ".mp3"; does..
Anyone know why it works with iOS Cordova, but not Android?
In my small HTML5 web-app, I want to play sounds in response to user actions. When the user clicks a button, in the onclick handler I play a sound like this:
url = "assets/sounds/buzz" + (this.canPlayMP3 ? ".mp3" : ".ogg");
sound = new Audio(url);
sound.load();
sound.play();
This works great on Firefox. Unfortunately, on an iPad (iPad 2 running iOS 5.1.1), I get a 2-second delay before the sound is played. This happens every time I play the sound sample, not just the first time.
The MP3 file is 9KB long. The iPad is connected to the network using exactly the same Wifi connection as the computer running Firefox.
How can I figure out what's going on?
You might want to create a single instance of the audio element for each sound:
var Sounds = {
cat: new Audio('/sounds/meow.ogg'),
bird: new Audio('/sounds/tweet.ogg')
};
Then you can play the same element over and over again:
function playSound(name) {
Sounds[name].currentTime = 0;
Sounds[name].play();
}
playSound('cat');
If iOS destroys your Audio objects, you could cache sound files in the cache manifest:
CACHE MANIFEST
# 2012-08-09:v1.3
NETWORK:
*
CACHE:
/sounds/meow.ogg
/sounds/tweet.ogg
How about moving the loading outside the handler e.g. make it global/preloaded? Then inside handler call play method only.