How do you change source in a web audio context - html

I'm making a game that changes some of it's object depending on what music is playing. After each song has ended I want my audio context to load in a new source and analyze that. However whenever I tried to do that I've gotten the error that an audio object or buffer can't be called twice.
After some researching I learned that ctx.createMediaElementSource(MyHTML5AudioEl) lets you create a sourceNode that takes the source from a HTML5 object. With this I was able to loop through different song.
However for my game I need to play/analyze a 30 seconds "remote url" that comes out of the Spotify API. I might be wrong but ctx.createMediaElementSource(MyHTML5AudioEl)does not allow you to analyze a source that is on a remote site.
Also the game needs to work on Mobile Chrome, which createMediaElementSource(MyHTML5AudioEl) does not seem to work on.
I might be on the completely wrong path here but my main question is:
How can I switch remote songs urls in web audio api. With it being compatible with mobile chrome.
Thanks!

First, as you found out, you can't set the buffer again for an AudioBufferSource. The solution is to create a new one. AudioBufferSources are intended to be light-weight objects that you can easily create and use.
Second, in Chrome 42 and newer, createMediaElementSource requires appropriate CORS access so you have to make sure the remote url sends the appropriate headers and you set the crossOrigin attribute appropriately.
Finally, Mobile Chrome currently does not pass the data from an audio element through createMediaElementSource.

Related

Storing local audio file data across page loads in HTML5

I am trying to make a webapp that will load a page from a remote server, but allow the user to play audio from files that are on their local drive (not downloaded from the remote server). I am able to get this to work, but I also need it to save what the user has done for subsequent visits. For example: the user loads a page, clicks a "choose file" button, selects an mp3, and plays it. The user then closes the browser, opens it again, returns to the page, and is able to play the same audio without having to select it again.
I understand that the audio playback is separate from the saving of the user's selection, but in this case one seems to dictate the other.
I am able to get the select-and-play functionality to work with this:
<html><body>
<script type='text/javascript'>
function handleFiles(files){
var file = window.URL.createObjectURL(files[0]);
document.getElementById('audioPlayer').src = file;
}
</script>
<audio id='audioPlayer' controls ></audio>
<input type='file' id='selectedFile'
onchange='handleFiles(this.files)' />
</body></html>
...but I do not know how to store the selected file data in a way that I can automatically load it on the next visit. What can I use to store that file location (or even the whole file itself if it comes to it) so that I can still play the audio without the user selecting the file again?
I kind of suspect that saving the local file url somehow may not be possible for security reasons, since auto-playing a file from the local file system without user interaction could be bad news.
File handles from File open dialog are not recycleable across different page load sessions.
The best you can do this that you copy audio data to a HTML5 localStorage and play it from there. Or upload the data to your server and play it from there.
http://docs.webplatform.org/wiki/apis/web-storage/Storage/localStorage
localStorage is limited to few megabytes depending on the browser.
At this time, Mikko's answer is the correct answer for my question, but I thought I'd share a possible alternative for anyone else who comes across this thread:
The FileSystem API looks like it would perfectly suit my needs in this case, but at the time of this writing, it is only supported in Chrome. If audio playback is a minor add-on feature to your webapp though, this might be an option to give Chrome users a better experience and other users would just be unaware that they're missing out.
In this HTML5 Rocks article, the author shows how to use it, including how to copy user-selected files into a local disk sandbox and how to get a url (needed in my case to audio playback) to those files.

Crossdomain policy behaviour on 302 redirects in AS3

I have crawled the web quite a lot these days, but couldn't get any accurate information on how crossdomain.xml files behave in case of 302 redirects; especially with the sandboxes having changed significantly over the last versions!
I am relatively new to flash... so any advice is more than appreciated!
I have been working on a project lately that uses audio streams with some sort of CDN distribution! what happens is that a common url is triggered, and then the user is dynamically redirected to the next best server available. In my case, i have no access at the server side of things (at least not anytime soon). And the only path providing an appropriate crossdomain.xml is the one performing the redirect. All the other dynamic paths provide exclusively content!
http://resource.domain.com (valid crossdomain.xml)
302 => http://dyn1.domain.com/...
302 => http://dyn2.domain.com/...
302 => http://dyn3.domain.com/...
I noticed that flash doesn't care much if i try to load the audio stream with something like...
var req :URLRequest = new URLRequest("http://resource.domain.com");
var sound :Sound = new Sound(req); // ie. effectively playing http://dyn3.domain.com
sound.play();
It gets both redirecting, and streaming done well! and doesn't bother for any crossdomain file and starts playing!
Although when i try something different, like setting up some custom headers to the request and loading the file with URLStream instead, everything gets messy! Well, the redirect gets done, as expected but all of a sudden i need another crossdomain file in the redirected location!
Is there any explanation to whats happening and eventually ways to resolve this?!
Thanks for your time!
It comes as a site question : i noticed everything to work flawlessly while being in the local-trusted sandbox and errors happening mainly if not exclusively in the remote sandbox. is it possible that the local-trusted sandbox doesn't care about crossdomain policy files at all!?
Summary
Add crossdomain.xml to each CDN host or adopt to limited Sound functionality.
Details
SWF files that are assigned to the local-trusted sandbox can interact with any other SWF files and can load data from anywhere (remote or local).
Sound can load stuff from other domains that don't allow access using cross-domain policy with certain restrictions:
Certain operations dealing with sound are restricted. The data in a
loaded sound cannot be accessed by a file in a different domain unless
you implement a cross-domain policy file. Sound-related APIs that fall
under this restriction are Sound.id3, SoundMixer.computeSpectrum(),
SoundMixer.bufferTime, and the SoundTransform class.
Flash in general has pretty complex cross-domain policies but in your case the bottom line is that you'll need to have proper crossdmain.xml on each host except the one that serves the SWF:
3.1. If your file is served from http://resource.domain.com it's not required to have http://resource.domain.com/crossdomain.xml but it's really good to have one.
3.2. You will need to have proper http://dyn2.domain.com/crossdomain.xml explicitly allowing your SWF to access dyn2.domain.com to be able to use URLLoader and other APIs that provide access to raw loaded data.
3.3. There's a reason for these restrictions - cookies (and other ambient user credentials). If Flash would not require proper cross-domains after a redirect, one could access any domain with user cookies attached by simply loading his own redirector first. This means accessing all user cookie-protected data (e.g. mail.google.com) from any SWF on the internet that's running in your browser.

Audio tag security in html5

Long version:
I use html5 audio tag to play mp3 files on my website. With Flash I can stream mp3's and secure it for 95%.
With html5 it is easy to find out the mp3 location and just download it from there. Even if I secure it with unique hashes it is not hard to inspect the network tab in chrome and see the mp3 url with hashes.
I was wondering if there are other ways to secure the mp3 from being ripped and if it is worth the time. For example bandcamp does generate unique hashes but it is still very easy to download the mp3. For youtube you got download websites that can proces the flv stream and rip the audio and save it for the user as mp3 format.
The first layer of security I can think of is change the extension of mp3 files to .txt or another common format.
95% of the users don't spot the extension because it is hidden by default on windows and apple. This will prevent the first 95% of the users to spot and play the mp3 file.
Short Version
Any suggestions to prevent users from stealing mp3 files while using html5 audio tag.
Short Answer
No.
Renaming the audio file to .txt is not going to do anything to help the security of your mp3 audio file. If anything, it is going to cause you even more issues, because now, your mp3 audio file is going to be sent with the incorrect MIME type, which may cause issues with the browser's built in audio player.
The best suggestions that I can provide you is:
Make sure that your checking the REFERER http header, make sure that it is coming from the page that has the mp3 player on it.
Protect the mp3 file with a unique hash.
Don't allow the same hash to be downloaded twice*
*Note that even doing this could cause issues, for example, what happens if the user reopens a tab from cache, plays the file again, and the mp3 file is not cached?
And finally, at the end even after your mp3 file is the most protected mp3 file in the history of IIS and Apache -- what is stopping me from just opening up Adobe Audition, and recordinging the audio stream?
Although you are correct about Bandcamp's MP3 audio stream, the mp3 is not as high quality then just a normal download after purchasing an album.
The fact that even Google does not really have any decent protections on it's video streams should say something. A company that generates billions of dollars from video views on YouTube can't even make (or better put -- has not bothered to put in place) any viable methods for protecting their videos.
Kind of.
Grooveshark send a POST request to a server-side script for the MP3 that is being streamed which makes it very difficult to just access and spoof without dynamically creating a POST request yourself - especially seeing as you would have to then attempt to store the audio file that is collected. But you can use the new AudioContext to help solve this for most modern platforms...
I used a great example from HTML5Rocks.com to alter the headers used as follows:
var dogBarkingBuffer = null;
// Fix up prefixing
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
function loadDogSound(url) {
var request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded");
request.responseType = 'arraybuffer';
// Decode asynchronously
request.onload = function() {
context.decodeAudioData(request.response, function(buffer) {
dogBarkingBuffer = buffer;
}, onError);
}
//this is the encryption key
request.send("key=98753897358975387943");
}
Related
As you can see I am also sending a key value which could possibly be part of a public/private pair too. This should put anyone off attempting to intervene - other than simply recording the MP3 as it's playing, of course, but what could possibly stop that in any environment inside or out of a computer?
You could make the MP3s themselves unattractive. Some ideas:
Don't include album art, album info, etc. in your files (id3 tags). Even better, fill out all id3 tag fields with something like "This file is from myMusicSite.com".
Split your files into several smaller pieces, and then play them in sequence in the browser. Having to download all the individual pieces will make your files much less attractive. You may have problems with gapless playback, not sure how well that's supported though.
Encode and play them as a video, maybe with your logo or something as the video stream. The resulting files won't be much larger, esp. if you use a static image. This will mean that users can't play your files on mp3 players, phones, etc. easily.
Whisper your domain name or website name in the recordings a few times, as mentioned in the comments.

Articulate: Unsafe JavaScript attempt to access frame with URL Error

I am trying to play story_html5.html video from Amazon Cloud fount in a IFrame, "story.html" is working fine in Iframe, but when use story_html5.html, it gives error.
Unsafe JavaScript attempt to access frame with URL "URL1" from frame with URL "URL2". Domains, protocols and ports must match.
Please let me know about the solution.
Thanks,
Laxmilal Menaria
I believe the html5 version of the file may be called once the code determines it's needed. Based on this, your personal code may look like it's trying to hijack the process and causing the exception. W/out the exact code you're working with though, it's hard to say. This is just based on my pulling apart some of the files a while back.

Record Video from Browser using Webcam and Microfone inputs

I need to record a video through user browser using input from camera and microphone and send to my server. Since html5 still doesn't make that magic happen, I'm looking for flash solutions.
Do I really need some flash media server to do that, or can I do a POST request?
I want to get both inputs(webcam and microphone), put them in a .flv and send to my server.
I've seen some implementations using bytearrays to record and send, audio and video separated. The problem is that it generates a series of synchronization problems when you try to compose them in a single file.
If you're still looking for a solution check out:
http://framebase.io
They have an embed-able recording widget that can transcode the videos automatically. I'd check out the docs, but on success, you can run an API call to check the status of transcoding and download it to your server or you can just use your own S3 bucket.