HTML5 web audio seekTo for buffered source - html

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.

Related

How to embed streaming rtsp media into an html5 page

I have a security cam that sends via rtsp, which I'm able to capture on vlc player, but I want to embed that into my webpage. I've been searching for hours on how to do this, but have failed to find any recent documentation on how to do this.
I am not set on vlc either, so I'm basically trying to go from cam -> rtsp -> player (if required) -> html embed.
Any help would be appreciated. And I know this is an open question, but I'm failing to find what I need on the net, so I'm open to any solutions.
With that said, I'm not looking for 3rd party providers to send the stream to me. For security reasons, the stream will not exit the compound.
Please do not send me old links to old articles either. I have scoured and probably read them already, and my experience is that things have changed. I'm looking for some answers from people who have experienced similar issues and been able to resolve them. Thanks!
I. Open VLC and select "Open Network Stream" via the Media menu.
II. Input your IP camera's RTSP string (credentials included) i.e
rtsp://test:test#192.168.0.37:554/cam/realmonitor?channel=1&subtype=1
which would be for my IP camera.
III. Click the down arrow next to the Play button and select "Stream".
IV. For the destination set it to "HTTP" then select "ADD". In the port field this is where you can set what port VLC uses to stream the video. In this example I used 8080. The path you can leave as "/".
V. Check the box for Activate Transcoding and set the profile to "Video - Theora + Vorbis (OGG).
VI. Click the Screwdriver + Wrench icon, set encapsulation to Ogg/Ogm, the video codec to "Theora" then set the bitrate to what you want to broadcast the stream to your site at (for what its worth I simply use the same bit rate as I am having the camera stream at. In addition you can also set your framerate
VII. Using the sub tab "Resolution" you can use "Auto" for scale, width, and height. You can disable the audio codec if you camera does not have a mic or do not want to broadcast the audio, & disable subtitles. Finally click "Save" then "Next".
VIII. Check the box for "Stream all elementary streams" and then click "Stream". Keep in mind VLC will show a black box where video would normally be which is intended. You should see the video timer moving just above the Pause/Play button.
IX. Then drop this code into your page:
<video id="video" src="http://IP_of_VLC_computer:VLC_Port" autoplay="autoplay" width="videowidth" height="videoheight"></video>
One of mine is as follows:
<video id="video" src="http://192.168.0.4:8080" autoplay="autoplay" width="704" height="480"></video>
X. Load your web page to see what the video looks like. Do not be concerned if you see what looks like a green screen. Just refresh the page every 5 secs or so to force the page to update the stream. That is common with RTSP video transport.
To sum it up you are turning your PC into a transcoder by way of VLC to spit out RTSP video that is HTML5 friendly.
I uploaded a 1min 46sec video to youtube to show you how to complete this process:

HTML 5 Audio Tag long buffer time

I am currently using the HTML 5 audio tag in one of my projects. I load an MP3 file from an external source and then initiate it like that:
$("#audioPlayer").attr("src",audioStreamURL);
document.getElementById("audioPlayer").play()
This works fine, but I noticed that the Audio-Tag takes a long time to buffer before playing the file (Chrome and Safari), which causes a delay of a couple of seconds and thus reduces the user experience significantly.
Checking the console in Chrome, I noticed that the audio most times starts once ca. 5 MB have been "transferred".
I also checked if it is due to the server's latency and loaded the audio file in VLC-Player. However, here it started right away, with no delay at all.
Does anybody know, why Chrome does that? And even more important: Does anybody know a solution for that problem? A workaround or audio-tag alternative?
I would really appreciate your help!
Have a look at the "canplaythrough"-event of HTML5 Audio. This event fires when the Audio is able to play without buffering. You could bind a listener to that event, that will play the Audio.
Maybe this will be faster than just playing the Audio, which will wait for the complete file to be downloaded.
There I demonstrated how to preload an HTML5 Audio: preloading the next song in a playlist a bit before the current one ends

Stop download of streaming audio to HTML5 element with Buzz

I am using Buzz to abstract HTML5 audio for internet radio. This works well, but I need a way to stop downloading the stream when audio is stopped.
For example, when I start playing, I can see the network requests for the stream begin. When I stop audio, that data for the stream is still being transferred, as if it were a static resource. I need to either prevent that from happening, or get it to stop once audio is stopped.
I believe jPlayer does this by destroying the <audio> element, but I don't see any method for doing this in Buzz. Is it possible? If so, how?
After spending some time with the Buzz source, I don't see any method for doing this currently. Fortunately, the raw audio element is exposed, allowing something like this:
buzz.sound.prototype.destroy = function () {
this.set('src', '');
}
This probably messes up some internal state information for Buzz. I'm looking into that right now.

Web Audio API: seek, play-/buffer-progress

When you play audio using the audio element in Chrome you get annoying clicks and cracks. At least under my 64bit Linux installation, even after I formatted and installed a new Fedora version. (Firefox and Opera are fine, even IE9 in a VirtualBox Windows 7.)
But demos using the Web Audio API instead of the audio element have perfect sound. So I was wondering if I could use the Web Audio API like the audio element? But there are some things you seem not to be able to do with this API. Or am I missing something? The things I couldn't find where:
starting to play a file before it is completely loaded
getting buffer progress updates (depends on the previous point)
getting play progress updates
seeking
Is there a way to do this with the Web Audio API?
This is where I would use it: http://tinyurl.com/magnatune-player
I think you should still use <audio> for streaming at the very least. You can treat it as a MediaElementAudioSourceNode in web audio if you'd like:
var mediaSourceNode = context.createMediaElementSource(audioElement);
AFAIK, there is no way to stream web audio directly. In fact, the web audio api suggests that you don't:
4.9. The AudioBuffer Interface
This interface represents a memory-resident audio asset (for one-shot sounds and other short audio clips). Its format is non-interleaved IEEE 32-bit linear PCM with a nominal range of -1 -> +1. It can contain one or more channels. Typically, it would be expected that the length of the PCM data would be fairly short (usually somewhat less than a minute). For longer sounds, such as music soundtracks, streaming should be used with the audio element and MediaElementAudioSourceNode.
Unless you used a MediaElementAudioSourceNode (which I would assume suffer from the same issues you're having since it's just using an <audio> tag) AFAIK the answers to your questions are:
starting to play a file before it is completely loaded: No.
getting buffer progress updates (depends on the previous point): Possibly (You could check for progress events on the XHR)
getting play progress updates: No.
seeking: No.
In the meantime Chrome fixed the audio playback issues. So I don't need any workarounds anymore.

How did Scirra get HTML5 audio so perfect in Construct 2?

Check out this space shooter demo.
The HTML5 audio is perfect on Chrome 18 and Firefox 10. There is no lag in playing sounds and each sample plays perfectly. The last time I tried to play sounds using HTML5 audio and JavaScript I couldn't get a sound to play more than once.
What sorcery is Scirra doing to make this so perfect?
I'm the developer of Construct 2, so I hope I'm sufficiently qualified to answer your question :)
HTML5 audio is indeed a mess, so I've gone to considerable lengths to try and make it bulletproof in Construct 2. Here's an outline of what I've done:
Use the Web Audio API
HTML5 audio appears designed for streaming music, so a HTML5 Audio object is kind of a heavyweight object. Playing 10 sounds a second with it like Space Blaster does can easily seize up the browser. On the other hand, the Web Audio API is a high-performance audio engine with routing, effects, and lightweight sound playback. It's perfect for games. Audio buffers and audio playback are separated, so you can have one data buffer and efficiently play it many times simultaneously, whereas some browsers are so buggy if you play a HTML5 sound a few times it re-downloads it each time! Since it was actually designed for games and such, you can happily play back tonnes of sound for ages and it will still hum along nicely. It can also use HTML5 audio as a sound source, although I only use HTML5 audio for things the user has designated as music tracks (since that's where you'd prefer to have streaming - typically everything else in the Web Audio API is fully downloaded before playing).
The Web Audio API is supported in Chrome, has also made it in to iOS 6+ (although it's muted until you try to play some audio in a touch event), Firefox are working on support, and it should be coming soon to Chrome for Android. So on these platforms audio will be significantly more reliable.
More info on HTML5Rocks and the proposed spec - you'll have to use the spec as the documentation for now, there's not much else out there.
Other browsers: implement an audio recycling system
The Web Audio API isn't yet supported everywhere, notably IE, which means you still need to crowbar HTML5 audio in to something that might work for games for backwards compatibility. The way to do this is to recycle audio objects.
The player's laser in Space Blaster fires 10 times a second - and that's not including any other sound effects! As I mentioned earlier, Audio is kind of a heavyweight object, so if you're doing new Audio() 10+ times a second, lo and behold, the browser eventually dies and audio starts glitching up. However, you can drastically reduce the number of Audio objects created by recycling them.
Basically, for each sound effect, keep a cache of every Audio object you've created with that sound as a source. Then, when playing a new sound, search the cache for any sound effects which have finished playing (the ended property will be true). If you find one, rewind it back to the beginning (currentTime = 0) and play() again. Otherwise, create a new Audio() object in the cache.
Since the player's laser sound effect is short, instead of creating 600 Audio objects a minute, there will just be 3 or 4 that it keeps cycling round. Some browsers unfortunately will still download it 4 times (Safari did this last I checked!) or have high latency the first time each sound buffer is played, but eventually the browser catches up since the same buffers are always being reused. So basically sound might be a bit weird for a few moments, then it clears up. We also use the HTML5 app cache so next time you play everything loads from disk, so subsequent plays should perform well immediately.
That's basically it. It's still a little dodgy on the first play with HTML5 audio, but every time after that should be fairly solid providing the browser has a sane audio implementation. There are a number of ways to try to clone Audio objects, but I've found that rewinding existing Audios works best.
There's no SoundManager or any Flash/plugin-based fallbacks at all since we make a point of being pure HTML5.
We also support audio APIs provided by PhoneGap and appMobi for mobile, since HTML5 audio on mobile isn't even worth trying. That makes a total of four audio APIs our audio engine wraps, and yes, it does look like a frankenstein mess, but it works.
That's it. I suppose our competitors will read this, but who cares when there's SO rep to be had???!!!1111