intro: I'm making a html5 game atm, and right now when the user taps the screen i have it playing a sound.
ProblemA: In chrome, the sound plays , but eventually stops playing all together even if i try to refresh the page ( the debug console doesnt show any errors either ) and i have to restart my browser to get the sound to play it again.
ProblemB: Also, the sound doesnt load on my ipod touch. But the game does when i dont load sounds.
i'm not using any api's or librarys. Any links to articles, or such would be helpful.
Edit: Heres some sample code of what im doing.
function loadSound(name,url){
// Increase how many assets we have
_rsvEngineReference.assetCount++;
_rsvEngineReference.assetCollection[name] = new Audio();
_rsvEngineReference.assetCollection[name].src = url
_rsvEngineReference.assetCollection[name].addEventListener('canplaythrough',function(){
_rsvEngineReference.numAssetsLoaded++;
},false)
_rsvEngineReference.assetCollection[name].load();
}
function playSound(name)
{
_rsvEngineReference.assetCollection[name].play()
}
Related
I'm using JW Player to live stream content onto a web page. The player is backed by an open-source library called cine.io.
My issue is that the player falls back to an HTML 5 video element for all mobile web, both on iPhone and Android. There are some differences between the flash solution of JW Player and HTML5 - notably that if a live stream starts, then stops, then restarts, the video element will not pick up the restarted stream.
This is a problem since streams often drop in and out - and the flash solution does pick up the restarted stream.
I tested a bunch of listener methods on the video and the only one that signalled that the stream had ended was a "time update" listener:
$video.on('timeupdate', function(){
//Do something
});
However none of my attempts to re-open the stream have been effective.
Is this even possible? Can anyone provide pointers?
Would an example like this work?
http://support.jwplayer.com/customer/portal/articles/1442607-example-a-custom-error-message
I have web application(similar to Karaoke) where user can record his voice over instrumental.
After recording user plays back recording. Here I play instrumental in <audio> tag and voice using web audio api. To sync both audios on play/pause I calculate time like this
pausedAt = Date.now() - startedAt;
startedAt = Date.now() - pausedAt;
This works fine. Issue is when user uses slider on audio tag to move forward/backward. I am thinking of solution like this
Use ontimeupdate event, stop the voice and then use startAt(currentTime) where currentTime is of instrumental playing in audio tag.
Since there is no seekTo function in api, I have to stop and then start audio. Is there any better solution for this?
Second issue I face is seeking on audio tag is not smooth. If I arbitrarily clicks on progress bar sometimes it doesn't work. When I saw network tab in developer tool window I saw something like shown in image. It sends out some 600 requests and some 86 MB data downloaded whereas file size is less than 10 MB.
You really should use the Web Audio API to do this. will never give you precise synchronization, and it will rely on streaming to seek - which is going to result in extra downloading, as you saw. Just load the song via XHR and decodeAudioData, and provide your own playback controls.
I'm trying to play MP3 or Ogg file, I create auto element (without appending it to DOM)
var $audio = $('<audio>', {preload: 'auto'}),
audio = $audio.get(0)
audio.src = "url/of/ogg/mp3 file"
audio.play()
Audio is not playing on iPad (it plays on desktop however)
If it's the same issue as with Video and I heavily think so:
The problem is, that on mobile iOS devices, Steve Jobs wants you to press play, before a video or audio file is loading. That stops kids from loading huge videos mobile without their explicit permission.
This is a business decicion of Apple. There are currently no workarounds the community is aware of.
Found another SO source:
Duplicate Question
Before I get flamed to death, I know this doesn't work currently due to Apple's concern over downloading an audio file automatically.
However, my question is: Has anyone found a cunning workaround yet? I just want to play a start up sound on the launch of a game and currently have to wait for the user to click somewhere before I can play the audio. One of you clever chaps must have got this working by now?
There is no chance to get autoplay working in mobile browsers. Android and iOS doesn't allow it and personally I think that is a feasible confinement! Imagine every second website you will open plays and ugly sound at start!
But you can make a little hack, so that the user will not remark that he currently started the audio for your application:
You WILL need an user interaction to start your audio. So, your app or game maybe has a startscreen or a welcome button which needs a click to get to mainmenu or start the game. Bind to an user event (the accepted events are: "click", "touchend", "doubleclick" and "keydown") and call the load() method for your <audio>.
Bind to the "canplaythrough" event of the <audio>. This event is triggered when your source is ready to play. Here you can now call play(), pause() or wait for other interactions. So the audio is ready but now you have full controll when to start or stop the sound.
I also advise you to use audio sprites on mobile clients. iOS (and Android?) internally implemented audio support through a Singleton. That means that you cannot, like in desktop browser, have 10 audio elements and play differents sound at once. You can only play one file!
So changing the source for different sounds takes to much time. With an audio sprite you can start your sprites when the user first interact with your website or game. Pause your sprite and when you need to play sound you have to set the currentTime to the beginning of the sprite and pause the sprite when currentTime of your file reaches the end of your sprite. There is an timeupdate Event where your can check the currentTime of your sprite.
If you are more interested I can prepare my javascript audio sprites player for you!!
Only solution I have seen so far is to create a shell app and put the web app inside a UIWebView.
http://flowz.com/2011/03/apple-disabled-audiovideo-playback-in-html5/
UIWebView.allowsInlineMediaPlayback = YES;
UIWebView.mediaPlaybackRequiresUserAction = NO;
I also would really like to know how to do this in a plain-old web app.
I believe I just solved this for my own app.
The steps,
Controller loads up,
Then.... in viewDidLoad
have your web view load the HTML : loadHTMLString:htmlFile baseURL:[self getBasePath]];
THEN... set mediaPlaybackRequiresUserAction = NO on the webview.
If you set it too soon, I think the load for the html resets it.
I have a bot chat app that has voice messages and I needed them to be autoplayed whenever needed ... so here is what worked for me in my angular app :
just attach a click eventlistener to document and call player.load(), after that whenever you set player.src = x; it will autoplay.
<audio id="voicePlayer" controls autoplay playsinline #voicePlayer></audio>
#ViewChild('voicePlayer', { read: ViewContainerRef }) voicePlayerRef: ViewContainerRef;
...
ngAfterContentInit(): void {
this.voicePlayer = this.voicePlayerRef.element.nativeElement;
document.addEventListener('click', this._onDocumentClick.bind(this));
}
_onDocumentClick() {
this.voicePlayer.load();
document.removeEventListener('click', this._onDocumentClick);
}
...
this.voicePlayer.src = 'x';
HowlerJS creates is a workaround. The user doesn't need to allow autoplay for the audio to be played automatically
Explanation from Docs on how this workaround is created :
howler.js is an audio library for the modern web. It defaults to Web Audio API and falls back to HTML5 Audio. This makes working with audio in JavaScript easy and reliable across all platforms.
I am porting a vehicle in-dash display unit app over to the browser. The big goal is to get it running completely within Mobile Safari.
It's an HTML5/JS music app that relies heavily on jQuery.load to move around between different "screens" by loading in page fragments.
The issue is that when a user selects a track to play, they are taken to the "now playing" screen, which should start playback of the track. The track is not playing though once this screen is reached, and the user instead needs to explicitly click play from this screen in order for audio playback to start. Once this has happened for the first time, autoplay works for the duration of the app.
I understand that Mobile Safari intentionally put blockers in place to prevent audio from autoplaying so that web apps are kept from consuming data unless in direct response to user input.
The thing is, my audio playback IS in direct response to user input...sort of. However, a bunch of things need to happen before my playback actually starts, and those things happen within the now playing page (calling API to get URL for track to be played, report user is playing track, get track metadata, yatta yatta yatta).
To try and get around this, I have the app preload a silent .1s mp3 file into the audio element on startup. Then in direct response to a click event to transition to now playing screen, I call .play() on the audio element.
I assumed that having a call to .play in direct response to user input would the subsequent call to .play() within the now playing page to work, since this is the behavior I had previously observed.
Only, it didn't seem to make any difference.
Any ideas on how I can adjust my flow in order for audio playback to start after loading the now playing screen?
EDIT:
Added some code snippets below
Vehicle.audio = {
init: function () {
audioElement.setAttribute("src", "/audioinit.mp3");
audioElement.play();
},
play: function (source) {
log("VEHICLE: playing audio from source " + source);
Vehicle.audio.stop();
audioElement.setAttribute("src", source);
audioElement.play();
},
In response to user selecting a track:
$(document).on("click", "a.play-track", function () {
Vehicle.audio.init();
/* my wrapper function for jQuery.load() */
replace_wrap("nowplaying.html");
});
Then on the now playing page, Vehicle.audio.play() is called.
The thing is, my audio playback IS in direct response to user input...sort of. However, a bunch of things need to happen before my playback actually starts, and those things happen within the now playing page (calling API to get URL for track to be played, report user is playing track, get track metadata, yatta yatta yatta).
Try adding a "touchstart" event listener to the entire "now playing page" which will then synchronously call .play() on the audio element:
$(document).one("touchstart", function () {
Vehicle.audio.init()
})
This way as soon as an iOS user touches anywhere on the now playing page, the audio should begin loading/playing.
AFAIK it is a restriction placed intentionally by iOS. User must interract with the device (touch/click event) before the script is allowed to start playback.