Gapless Transition from Video to Video using html5 - javascript

I am trying to create a feature where a user can change (back and forth) between multiple videos while maintaining a single consistent audio. Think of being able to watch a concert from multiple angles but listening to a single audio. The trouble I am having with this feature is that there can not be a lag between the changes in video or the audio will no longer sync with the videos (especially true after multiple changes).
I have tried two methods, both using html5 only (I would prefer not use flash although I will eventually have a fallback) that have not worked seamlessly, although depending on the browser and hardware, it can come very close.
Basic Methods:
Method 1: Preloading all videos and changing the video src path on each click using javascript
Method 2: Again preloading video and using multiple tags and changing between them using javascript on each click.
Is there anyway to get either of these two methods to work seamlessly without a gap? Should I be using a slight of hand trick, like playing both videos concurrently for a second before revealing the second and stoping the first? Can this just not be done with html5 players? Can it be done with flash?
I have seen this type of question a couple of times with both video and audio with no clear solution, but they were a couple of months old and I was hoping there is now a solution. Thanks for the help.

Worth adding that it is possible with the MediaSource API proposed by Google. This API allows you to feed arbitrary binary data to a single video element, thus if you have your video split into chunks you can fetch those chunks via XHR and append them to your video element, they'll be played without gaps.
Currently it's implemented only in Chrome and you need to enable Enable Media Source API on <video> elements in chrome:flags to use it. Also, only WebM container is currently supported.
Here is an article on HTML5Rocks that demonstrates how the API works: "Stream" video using the MediaSource API.
Another useful article that talks about chunked playlist: Segmenting WebM Video and the MediaSource API.
I hope this implementation gets adopted and gets wider media container support.
UPDATE JUN 2014 Browser support is slowly getting better: (thanks #Hugh Guiney for the tip)
Chrome Stable
FF 25+ has a flag media.mediasource.enabled [MDN]
IE 11+ on Windows 8.1 [MSDN]

Did you find a better way to do that?
I implemented a double-buffered playback using two video tags.
One is used for the current playback, and the second for preloading the next video.
When the video ends I "swap" the tags:
function visualSwap() {
video.volume = video2.volume;
video2.volume = 0;
video.style.width = '300px';
video2.style.width = '0px';
}
It has some non-deterministic behavior, so I am not 100% satisfied, but it's worth trying...

Changing the SRC tag is fast, but not gapless. I'm trying to find the best method for a media player I'm creating and preloading the next track and switching the src via "ended" leaves a gap of about 10-20ms, which may sound tiny, but it's enough to be noticable, especially with music.
I've just tested using a second audio element which fires off as soon as the first audio element ends via the event 'ended' and that incurred the same tiny gap.
Looks like (without using elaborate hacks) there isn't an simple(ish) way of achieving gapless playback, at least right now.

it is possible. you can check this out: http://evelyn-interactive.searchingforabby.com/ it's all done in html5. they are preloading all videos at the beginning and start them at the same time. didn t had time yet, to check how they re doing it exactly, but maybe it helps if you check their scripts via firebug

After many attempts, I did end up using something similar to Method 2. I found this site http://switchcam.com and basically copied their approach. I pre-buffered as the video start time approached and then auto-played as the videos starting point hit. I had the current videos playing simultaneously (in a little div - as a UI bonus) and users could toggle between the videos switching the "main screen view". Since all videos were playing at once, you could choose the audio and the gap didn't end up being an issue.
Unfortunately, I never ended up solving my problem exactly and I am not sure my solution has the best performance, but it works okay with a fast connection.
Thanks for everyones help!

Related

p5.sound distord sound on mobile?

I'm developing an experimental website which uses p5.sound to analyze a certain song and I use the frequencies of this song to draw on a canvas.
The problem is that the sound sounds great on my laptop & pc, but when I try to listen it on mobile, it's starting to flicker, having noisy parasites and it's slowed down (a lot...)
I've tried on others phones and it's the same.
Even on the official doc : https://p5js.org/examples/sound-sound-effect.html
it's laggy for a simple ring sound.
Does anyone experienced this issue?
It's working fine if I use regular JavaScript and html <audio> elements.
Also, do you know others simple ways to get frequencies of a sound played from html <audio> elements?
So I found the solution by actually look how p5.sound was working.
I ended up using the Web Audio API.
I created an audio context then an analyser and the sound was no longer distorded on mobile.
The process is almost the same as if you where using p5 :)

Preloading 50+ Videos on Page Load Without Affecting the DOM

I'm working on a project where several videos are added to the HTML dynamically by JavaScript when they're needed to play, sort of like a remotely-controlled presentation. The order the videos will need to play is unknown at the time of page load and each video is under four seconds. However, the videos are large and naturally need to appear seamless when moving from when to the next, but since the videos are so big and, in some cases, loaded through the Internet, loading usually isn't seamless.
The way I'm adding videos right now is something like this:
$("body").append("<video class='onscreen' autoplay><source src='"+c.video+"'></source></video>");
Where c.video is a relative path to the video source.
Is there any way to preload videos directly from JavaScript beforehand without adding to the HTML? If not, what would be the best way to add to the HTML without having the video visibly playing and allowing for it to be dynamically added later?
I've seen several similar questions on StackOverflow (like this one) but they're all concerned with adding the video and only playing it later, once loaded. I'm sure it's possible to adapt the code presented in those, but I'm not quite sure how to go about doing it, especially as I don't understand some of the concept (please feel free to expand on your answer a bit; I don't just want code snippets!).
If it effects things at all, this will, in the foreseeable future, only have to run on Firefox and the videos will likely all be OGV (though there may be exceptions).

iOS html5 video on mobile safari

I have a video I'm playing on iOS 4.2 where I'm listening in the timeupdate events and pausing video at certain times. This is fairly accurate. However, I also have player controls that seek to certain parts of the video using current time.
There appears to be a bug where the time seeked is never accurate - not accurate enough for what I need to do with it. The problem gets worse as the length of the video increases and I've also noticed that at the beginning of the video the seek time would be around 0.5 miliseconds off the time I specify but as I try to seek further along in the video this increases. Seeking 2 minutes into a video files is off by around 2 seconds.
I don't think this is a probloem with my code as I've replicated the same behaviour using the opensource Jplayer.
http://www.jplayer.org/HTML5.Media.Event.Inspector/
currentTime has caused me nothing but problems on iOS. It didn't even work on 3.2.
Is the problem I'm having now a known bug and is there a workaround for this?
I ran a test to see if I could confirm the same behavior on my emulated build of iOS 4.1.
I definitely experienced similar problems on both the iPhone and iPad. But I didn't notice the offset growing proportionately as the video got longer - it seemed more random. If I had to guess, I'd say the video is seeking to the keyframe prior to to your requested time rather than to the correct position.
The iOS devices seem to be reporting currentTime accurately... You are able to pause the video in the correct place and it looks like the timecode on the iPhone matches that on the desktop. It just won't queue up in the correct place.
What kind of video are you using? I tested h264 video encoded with ffmpeg.
It might be worth adding more keyframes to your video or looking for a switch in your encoder that makes the content more easily seekable. I know ogg video has support for indexing (see this post). That won't help this issue, but we might be able to find a parallel solution that works here.
This is going to be a problem for me very soon, so I'm very interested to see if you found a fix. Please post back if you have.

Multi-channel audio support in the browser on iOS and Android

I found this link to a page here on StackOverflow about "Creating Audio using Javascript in <audio>", and this page on how to play audio on multiple channels. I found that the iPhone supports the audio tag and the Audio object in Javascript to play single channel audio, but is there a way to play audio on multiple channels?
Maybe I'm over complicating this, so this is what I'm trying to do. I want a way to make a graceful audio player in Javascript that supports transitioning from one audio file to another. The way I was going to implement this is to incrementally reduce the volume on one channel while incrementally increasing the volume on the other channel so I'd get a kind of fade effect. Is there a simpler solution to this using only Javascript? I guess another solution would be to reduce the volume to a certain point, start the new audio file on the same channel, then increase the volume again. This circumvents the need for fading, but I would like to fade if at all possible.
Is this possible? I know the HTML5 spec isn't finished yet, but is there some kind of workaround that you know of? Do any of you have ideas for another approach?
From what I can tell from this post about playing audio in the Android browser, this isn't supported yet, but do any of you know if it will support multiple channel audio once the audio tag is supported? Does opera mini support this?
This is an old question I know :).
iOS Safari does not support multiple audio objects playing at the same time. Also, it is not possible for having a fade-in/out effect for iOS, as the only way to change the volume setting is from the hardware itself. Apple decided to give this ability only to the device user. Volume setting is not writable by javascript. It is not even readable (always returns 1).
You can check out the Safari documentation for iOS for more info.
For Android, to be honest I have no idea.
There's no direct way that I know of to have multiple channels on an audio tag, but check out this blog post on using multiple audio tags to simulate multiple channels. http://www.storiesinflight.com/html5/audio.html
I know this is a total hack but try this trick I came up with...
Go to the page below and type on the home row keys to play a blues riff (type multiple keys at the same time etc.)
http://davealger.com/jthump/
The way this works is to create invisible <iframe> components that play a sound before destroying the frame.
I know it is a total hack and I look forward to better HTML 5 multi-channel audio support in the future.

Is there a reliable way to time javascript animations with an audio file playing in the browser?

For example, I want the page to play an audio file while at the same time have some bullets slide into view at just the right moment that said bullet is talked about in the audio file. A similar effect would also be used for closed captioning. When I say reliable I mean specifically that the timing will be consistent across many common platforms (browser/OS/CPU/etc) as well as consistent in different sessions on the same platform (they hit refresh, it works again just as it did before, etc).
NOTE: It's OK if the answer is 'NO', but please include at least a little quip about why that is.
Check out this animation, which synchronizes a 3D SVG effect to an audio file.
The technique is explained in a blog post at http://mrdoob.com/blog/page/3. Look for the one entitled "svg tag+audio tag = 3D waveform". The key is to create a table of volume values corresponding to the audio file.
You'll obviously have some work to do in studying this example and the Javascript it uses to adapt it to your scenario. And it will probably only work in browsers that support HTML5.
Given the current situation and HTML5 support, I would solve this using Flash.

Categories

Resources