HTML5 Local Storage of audio element source - is it possible? - javascript

I've been experimenting with the audio and local storage features of html5 of late and have run into something that has me stumped.
I'd like to be able to cache or store the source of the audio element locally to enable speedier and offline playback. The problem is I can't see how this is possible with the current implementation.
I have tried the following using WebKit:
Creating a manifest file to set up local caching but the audio file appears not to be a cacheable item maybe due to the way it is stream or something
I have also attempted to use javascript to put an audio object into local storage but the size of the mp3 makes this impossible due to memory issues (i think).
I have tried to use the data uri and base64 to use the html as a audio transport that can be cached but again the filesize makes this prohibitive. Also the audio element does not seem to like this in WebKit (works fine in mozilla)
I have tried several methods of putting the data into the local database store. Again suffering the same issues as the other cases.
I'd love to hear any other ideas anyone may have as to how I could achieve my goal of offline playback using caching/local storage in WebKit.

I've been trying to do this myself, on the iOS (for iPhone / iPad) but it refuses to cache audio files in offline, even if in Cache Manifest.
It does not error, but instead simply pretends to have played the audio element if invoked via JavaScript without a control. If it's embedded with a control, it displays an alternate control that says "Cannot play audio file.". It works fine if the application is able to go online.
It seems not to cache the audio, playing another sound resource seems to cause it to clear the previous resource from memory - this is pretty worthless functionality even when online.
I have experimented with base64 encoding the audio as data URI's. This works in Safari on the desktop (at least for fairly short samples of around 20-30k that I've been using) but seems not to be supported at all on iOS - it silently does nothing, which is highly annoying.
I don't know about other vendors - Google Chrome used to not support data URI's for audio but perhaps they fixed it... - it seems like it's not possible for now though.
Update: Minor discrepancy with iPhone OS 3.x (tested with 3.1.2): If an audio element is specified in an offline web app but it doesn't have a control, it displays a non-interactive control with a non-animated spinner on it (which it definitely shouldn't do). I assume this is fixed in iOS 4.x (which should be out next week).

So it's been a while since I asked this question and I thought i'd give some info about how we solved it. Basically we encoded the data into PNG's using a similar technique to this:
http://audioscene.org/scene-files/yury/pngencoding/sample.html
Then cached the image on the mobile device using html5 local storage and accessed it as needed. The PNG's were pretty big but this worked for us.

I spent a while trying to do this for a game I'm making, and since as far as I could tell browsers (Firefox and Chrome) still don't support caching of audio elements I thought I'd post the solution I found.
There is a workaround described here: http://dougx.net/plunder/index.php#code
I can confirm it works pretty well, but is probably better suited to smaller files. As he describes here (http://dougx.net/plunder/GameSounds.txt), you encode the audio as base64 strings, and give them a data:audio/ogg;base64 (or any compatible audio format) header, which HTML5 audio can then read in. Because this is just a string, the browser will cache it.

I guess it would be preferable to get the manifest approach working, since this feels like the most relevant mechanism for locally caching the file.
What happens if you alter the audio file's HTTP headers, e.g. Content-Type and Expires? Does the browser do something different if the file extension is changed?

I see you've had no luck so far.
You might want to take a look at JAI (JavaScript Audio Interface) ("the world's first javascript interface for web <audio>"). Or get in touch with Alastair MacDonald, who wrote it.
Failing that, the HTML5 Doctor may be able to assist.

Adding video and audio files to local storage works with iOS 4.3.
I just added a video and an audio file to manifest and they both got downloaded to offline storage on iPad.

Related

Screensharing over WebRTC and browser support

I am trying to build screensharing over the browser. I am trying to find the best native implementation and did some initial online research
MediaDevices.getUserMedia() - available in FF. In chrome its a little weird
WebRTC Tab Content Capture - I see its in proposal stage
Screensharing a browser tab in HTML5 - A blog explaining other methods
Researching above everything seems to be around 2012 time frame and I want to know what is the latest?
Question: Which current technologies/javascript API can i use and what is its support across browsers
Screensharing is alive and kicking in Firefox, but atm requires the user modifying about:config. See my answer to another question for how. I believe they're working on removing that obstacle.
Chrome is similar but not quite the same, and AFAIK requires the user to install an extension.
I don't believe other browsers support this natively yet.
You can save html document onto <canvas> or <foreignObject> of <svg> element, then send data URL, ArrayBuffer or Blob of <canvas> or <svg>; or alternatively, send html document as encoded string.

How to modify the content of WebRTC MediaStream video track?

I use WebRTC in a scenario in which the client video stream is recorded on a third-party server https://tokbox.com/. I would like to put some kind of watermark in the recorded video.
Investigation brought me to this page http://w3c.github.io/webrtc-pc/#mediastreamtrack and it seems that it is technically possible since it says that:
A MediaStream acquired using getUserMedia() is, by default, accessible to an application. This means that the application is able to access the contents of tracks, modify their content, and send that media to any peer it chooses.
This is exactly what I need, but I didn't find any examples or explanation of this function. I'd like to get some advice from WebRTC experts.
You need to use a canvas to route the video from getUserMedia to, modify it there, and then use canvas.captureStream() to turn it back into a MediaStream. This is great - except that canvas.captureStream(), while agreed to in the WG hasn't actually been included in the spec yet. (There's a pull request with the proposed verbiage that Mozilla wrote.)
As far as implementations: the initial implementation of captureStream() just landed in Firefox Nightly (41), and it's still behind a pref until a bug or two is fixed. You can enable it with canvas.capturestream.enabled in about:config. You can see a demo at Mozilla's test page for captureStream().
Doing it without canvas.captureStream() would be tough; you're best way would be to do getUserMedia->canvas-> and then use video.captureStream() (or captureStreamUntilEnded()) - however, video.captureStream is also waiting for formal acceptance. Mozilla has had video.captureStream() for some time, however, and I think it works in FF 38 (current release).

Object-URL alike way to play local audio files in Chrome for Android

I have a media player that uses object URL's to load files 'in an instant'. However, Chrome for Android doesn't support object URL's. what would be the best way to work around this problem? I was thinking about detecting wether the browser supports it, and then fall back on a file reader with data-URL's (readAsArrayBuffer).
I have already read through many questions, referring to using the web-audio-API. I however use this, but with createMediaElement, where the audio element plays the music.
As simple as it is, Chrome for Android doesn't support URL.createObjectURL(), we should indeed use webkitURL.createObjectURL().

Playing back 3gp audio recorded in Android Cordova elsewhere

I would like to be able to record audio on a mobile device, in a Cordova app, then play it back on desktop computers in web applications. However, I'm running into some nasty codec issues.
According to the Cordova docs:
Android devices record audio in Adaptive Multi-Rate format. The
specified file should end with a .amr extension.
This seems wrong. According to the info here, .amr files should have headers that start with:
#!AMR.4
However, audio files from my Nexus 7 have headers like this:
....ftyp3gp4....
Which seems to indicate they should have .3gp extensions.
Furthermore, I don't think there is native browser support (outside of Cordova), for either format. I found a JavaScript amr playback library, however it cannot convert .3gp files (i.e. the files android produces). I'm betting a similar approach could be used to decode .3gp files, however it seems like a daunting task to take on. I'm hoping to avoid that. If someone else would like to do it I would be forever grateful.
If there is no way to change the format that the Cordova Media API produces, a decoder will be necessary. A pure JavaScript decoding solution would be ideal, a flash converter would be almost as good. The other possibilities I've considered have some issues:
One possibility is to use another app to do the conversion. For example, ffmpeg for android. I would like to avoid that because launching intents from Cordova requires a plug-in that Phonegap Build doesn't provide, and the user would have to deal with installing and operating another app.
Another possibility is to do decoding in the cloud. I don't want to run any of my own web services if possible. I've tried encoding.com and was able to successfully convert one of my audio files into a mp4, however they don't yet have Dropbox file watch support. And if the audio files need to be encrypted before reaching the could, for example because of HIPAA, then cloud decoding becomes really complicated, if not impossible.
Please help. Thank you.
The problem is that there are not many encoding codecs included in Android. If you look at this table you can see what is available pre Android 4.1. Phonegap uses AMR-NB as the encoding type in a 3gpp container.
My recommendation to you is to decode in the cloud.

Web AVI Player?

I'm looking to play AVI files in a web browser however I can't seem to find a decent tool to do so.
The basic WMP object embed is what I'm using right now but it doesn't really do what I'd like it to do, and I can't really implement JavaScript into it. (AFAIK I can't. I done a little digging and that's the conclusion I came to)
I've also tried DivX though I don't really like it. It has adverts, and I've no idea if JavaScript can be included either.
AFAIK Flash doesn't support AVI playback at all.
Does anyone know of any player at all that can play AVI files on the web, which I could possibly integrate some kind of JavaScript in (or has an API)?
Just a thought too, but would Java itself have anything like this?
The player also needs to be able to source the files like this:
file:\\Network-PC-Name\avi\avifile.avi
What you're looking for is WebChimera, there's no doubt about it. It has the most complex JS API ever made for web video, and it supports all file types.. it also supports "file:///" (for links like file:///C:/avi/avifile.avi).
It is open source and has no advertising. And the best part is that everything inside the player is editable, so you can skin it, add buttons and even add entirely new features to it with mostly just JavaScript. :)
Update
As you mentioned you need it to connect to file:///Network-PC-Name/avi/avifile.avi, this tells me you need this for some Local / Private / LAN use.
In this case, I think the best solution for you is to use WebChimera with Node-Webkit, as it will also give you a JS API based server environment.
WebChimera Player is already ported to NW for Windows and Mac:
https://github.com/jaruba/WebChimeraPlayerNW
On Windows, just download the package, and run nw.exe. To customize just edit the html pages. For Mac, just follow the instructions in the Readme.md.
The great part about using it like this, is that it already has the plugin embedded in the app, so you won't even need to install the plugin for the player to work.
The only thing I can't be fully sure of, is if Network-PC-Name can even be accessed through the file:/// protocol in it's normal usage. But this would still be possible anyway as you could map the network drive, and you can even map it programatically (with only JavaScript!) by using the child process exec to run the necessary command. (child_process is built in node-webkit natively)
flowplayer is recommended by this post:
Flash video player for AVI files (free for commercial use)
not sure about the file:\ source, as that's on your local machine and could be refused by the browser for security reasons

Categories