Cannot trigger "durationchange" of HTML5 audio - javascript

thanks for looking at my question. I am working on a HTML5 audio related project. And now I meet a question.
What I want to do is assigning an audio.src to another audio.src. Actually, it works well in my beginning demo. But it does not work in my current project. The original audio cannot be played. And I console out all it's loading procedure and figured out the problem happening in durationchange. But I have no idea what is wrong with it since my logic is very similar to my beginning demo.
Hopefully, someone here could help me find out what is wrong with my code. The following is my code:
// the original audio is Glogal.audio
var segs = $('.cutter-room .container').find('.seg-container');
var audio_self = "<audio id='player_0'>";
// add one more segment for the new cut part
$('.cutter-room').append(audio_self);
$('.cutter-room .container').append(cut.audio_seg); // audio_seg is the 'clothes' of audio tag, a GUI
// new_seg is the audio tag which I want to assign to
var new_seg = document.getElementById("player_0");
var temp = GLOBAL.audio.src;
new_seg.src = GLOBAL.audio.src; // if I comment this one, the original will be fine
And the following is my testing code, when the new <audio> inserted in DOM successfully, if I try to play the original audio, its durationchange will not be called:
/*for testing*/
GLOBAL.audio.addEventListener("loadstart", function(){
console.log('start loading');
});
GLOBAL.audio.addEventListener("durationchange", function(){
console.log("change duration");
});
/*end testing*/
By the way, I am sure that the music file is correct. Thanks again!
Update 2013/11/28
Here is the jsFilddle link. I am sorry that I don't know which music link should I put in the src so I just put my local path. The problem shown in jsFilddle is a little bit different from what I said above. In jsFilddle, there is nothing wrong with the original audio but the second one cannot play.
I found that it I just open the .html page, no server supported. There will be nothing wrong. But if I run it on a server locally, the duraionchange will not response. So does it mean that the problem happens on the server side, but not the js?
But it is unreasonable that an audio source cannot be assigned to another audio source with a running server. They are paths but essentially, they are still Strings, aren't they?

The thing is that browsers don't like having the several different players pointing to the very same mp3 on the same page.
So the trick can be to alter the url, to prevent caching, for example:
assign.src = original.src+"?foo="+(new Date().getTime());
jsfiddle

Related

Play a sound in JS when some text appear on the screen [duplicate]

This question already has an answer here:
How can I have a Tampermonkey userscript play a sound when a specific word appears on a page?
(1 answer)
Closed 4 years ago.
I want to monitor a website word changes. I am looking for a sound to autoplay when a given word appears on the screen.
This word might come embedded within a new div ID, so I am not monitoring a particular DOM object change, but a string/new-word that appears on the screen eventually.
In short, I am looking for a JS that plays a sound everytime the word "Customer" appears on the screen. I have tried this code (copy paste from someone else) so far and it plays a sound everytime the page reloads, but not when the word "Customer" appears on the screen.
HereĀ“s the code:
var player = document.createElement('audio');
player.src = 'https://dl.dropbox.com/u/7079101/coin.mp3';
player.preload = 'auto';
for (var i = 0; i <= 10; i++) {
if (i === 10) {
// Play a sound when i === 10
player.play();
} else {
console.log('Not yet!');
}
}
Of course this is just a piece of code that checks for something very different, but when fiddling around with it, I find that everytime I modify the formula it stops playing the sound on tab reload.
Let me start off by saying more info is required (see my comments above), and you should try and make an effort to first get some stub of code together that actually does/attempts to do what you're trying to achieve. StackOverflow is not some kind of code-requesting forum where you can ask others to write something for you.
Since you're new here, I'll try to get you started with some ideas:
It's still unclear to me whether you're trying to scan through a page 'of your own' (i.e. on your own server), or someone else's page (on another server).
Scanning the same page (on your server) that your javascript code is on
If you're scanning one of your own pages, and you can even run the javascript on that very page, your solution will be very simple (source: Javascript: how to check if a text exists in a web page ). I personally prefer the jQuery solution posted in this question:
var player = document.createElement('audio');
player.src = 'https://dl.dropbox.com/u/7079101/coin.mp3';
player.preload = 'auto';
window.setInterval(function(){
if($("*:contains('Customer')").length > 0){
console.log('Customer detected, playing sound...');
player.play();
}
}, 5000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Customer!
There is of course still he problem that you'll probably only want to play the sound once for every new occurance of the word 'customer'. This will require more advanced programming (you'll have to keep track of which words you've already played the sound for), which is kind of out of scope for this question.
Scanning a different page (on your server, or an external one*)
If you're loading a different HTML page (or other text-type page, doesn't really matter) you can also find your solution on StackOverflow (source: How to check if string exists on external page with JavsScript? ). In short, you'll perform an AJAX request to get the page, and then check for the word 'Customer'. *The same-origin policy will however prevent you from loading most external pages purely through javascript (read more: Loading cross domain endpoint with jQuery AJAX ), so you will need some kind of cross-origin plugin (read more in this topic).
var player = document.createElement('audio');
player.src = 'https://dl.dropbox.com/u/7079101/coin.mp3';
player.preload = 'auto';
var url= 'http://www.businessdictionary.com/definition/customer.html';
window.setInterval(function(){
$.get(url, function(data) {
if(data.indexOf('whatever') != -1) {
console.log('Customer detected, playing sound...');
player.play();
}
}, 'text');
}, 5000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Best of luck with your project, and welcome to StackOverflow. I will update my answer if needed, or when you provide more information.

How to make .MP3 Audio Player that prevents right click save target as... with Jquery

I have been building a website to sell my instrumentals / music and was trying to find a way to create a simple .MP3 audio player button that prevented users from right clicking save target as... while simultaneously hiding the actual .MP3 file link. I also needed it to only play one sound at a time (prevent sounds overlapping.) What I discovered is that if it could be heard, it could most likely be downloaded.
The method that I discovered (with help from the stackoverflow community) is not 100% full proof against users finding and downloading your .mp3 files, but it will make it a little more difficult.
https://jsfiddle.net/9a9jbqzz/1/
Steps
(Optional) The first step is to convert the name of your sound file to something confusing like an MD5 hash (this is not 100% necessary but it makes it a little more tricky), for this example I will be taking the values 'control.mp3' and 'smooth.mp3' then convert them to their md5 hash. Link to online MD5 Hash Converter (you could also name them randomly anything you want like 12345abc ect.)
control.mp3 in MD5 Hash form = cef83b993c716dd543b6fa4f053cc4a4
smooth.mp3 in MD5 Hash form = cbbe0ab9d89c68f24f4fadff907fa720
Now that I have the MD5 Hash version of my file names. I will rename my MP3 files to their corresponding MD5 Hash. cef83b993c716dd543b6fa4f053cc4a4.mp3 and cbbe0ab9d89c68f24f4fadff907fa720.mp3
I am now ready for code:
HTML:
<p><span class="play" key="cef83b993c716dd543b6fa4f053cc4a4">Play</span></p>
<p><span class="play" key="cbbe0ab9d89c68f24f4fadff907fa720">Play</span></p>
(Notice all you see is 'Key = cef83b993c716dd543b6fa4f053cc4a4' instead of somthing like src=path/control.mp3)
CSS:
.play
{
color:green;
cursor:pointer;
}
.pause
{
color:red;
cursor:pointer;
}
(I will make it so when clicked css changes you can edit this to have a background image button or whatever you like, this is just simple color change for example)
JQuery:
$(".play").on('click',function(){
var key = $(this).attr('key');
EvalSound(key);
var this_play = $(this);
$(".play").each(function() {
if ($(this)[0] != this_play[0]) {
$(this).removeClass("pause");
}
});
$( this ).toggleClass( "pause" );
});
var thissound = new Audio();
var currentKey;
var interval;
function EvalSound(key) {
if(currentKey !== key)
thissound.src = "http://99centbeats.com/beats/" + key + ".mp3";
currentKey = key;
if (thissound.paused) {
thissound.play();
interval = setInterval(function() {
if(thissound.currentTime == thissound.duration) {
clearInterval(interval);
$('.play').removeClass("pause");
}
},100);
} else {
thissound.pause();
thissound.currentTime = 0;
currentPlayer = thissound;
clearInterval(interval);
}
}
(You could put this in a .js file and name it something real confusing like an md5 hash, <script src="c50ea22a5484a69f1eb22f8aaccae296.js"></script> Just make sure this is after your HTML in order to work.)
This method is not 100% perfect and will not prevent all users from downloading your .mp3 files, but it will make it not as easy as just right clicking save target as. If you are trying to sell music for a living you may want to use this. In reality it seems the ones who will pay, are gonna pay regardless, and the ones who are gonna download it without paying are gonna do that regardless too, so in the end you are not really stopping much, but this is a technique I wanted to learn and implement. I decided to share this because I couldn't really find anywhere that did exactly this, You may want to do something different but this could possibly give you some ideas. Thanks for the people who helped me with the code!
Some stackoverflow / jsfiddle posts that helped:
Stopping/Pausing audio when another audio file is clicking using jQuery
Javascript Audio -- multiple play buttons on page with separate audio files
Hide MP3 full url
http://jsfiddle.net/dledet1/55vag/11/
You can never make it 100% proof, since you need to serve the data, so it can always be captured.
Good job though, looks pretty obfuscated, though it is not really a question.
How about cutting track into 30 seconds or 1 minute fragments and play them in sequence?
Google Music does that. Won't stop from downloading, but 95% of users will find it difficult to merge them into single file.

export "saved for later" from (evil) feedly

i'm trying to migrate from feedly as it is unacceptable (at least to me) that a search query is (fully) enabled only by a pro version.
Anyhow, to export my lengthy list of "saved for later" i found some lovely scripts:
Simple script that exports a users "Saved For Later" list out of Feedly as a JSON string and feedly-to-pocket. where i am instructed to:
You must switch off SSL (http rather than https) or jQuery won't load!
so i though i did by adding (ubuntu 14.04/chrome 40 x64)
--ssl-version-min=tls1
to my /usr/share/applications/google-chrome.desktop file (all lines starting with Exec=). However when i try to run it in the browser console i get
This request has been blocked; the content must be served over HTTPS.
So, any suggestions? (also, excuse me for noobness)
Go to your Feedly "saved" list and scroll down until all articles have loaded.
Open console and paste the following Javascript into it:
function loadJQuery() {
script = document.createElement('script');
script.setAttribute('src', '//code.jquery.com/jquery-2.1.3.js');
script.setAttribute('type', 'text/javascript');
script.onload = loadSaveAs;
document.getElementsByTagName('head')[0].appendChild(script);
}
function loadSaveAs() {
saveAsScript = document.createElement('script');
saveAsScript.setAttribute('src', 'https://cdn.rawgit.com/eligrey/FileSaver.js/5733e40e5af936eb3f48554cf6a8a7075d71d18a/FileSaver.js');
saveAsScript.setAttribute('type', 'text/javascript');
saveAsScript.onload = saveToFile;
document.getElementsByTagName('head')[0].appendChild(saveAsScript);
}
function saveToFile() {
// Loop through the DOM, grabbing the information from each bookmark
map = jQuery(".entry.quicklisted").map(function(i, el) {
var $el = jQuery(el);
var regex = /Published:(.*)(.*)/i;
return {
title: $el.attr("data-title"),
url: $el.attr("data-alternate-link"),
summary: $el.find(".summary")[0].innerHTML,
time: regex.exec($el.find("span.ago").attr("title"))[1]
};
}).get(); // Convert jQuery object into an array
// Convert to a nicely indented JSON string
json = JSON.stringify(map, undefined, 2);
var blob = new Blob([json], {type: "text/plain;charset=utf-8"});
saveAs(blob, "FeedlySavedForLater" + Date.now().toString() + ".txt");
}
loadJQuery()
Source: Feedly-Export-Save4Later
Not javascript but here is how I saved a html page with all the links and excerpts...
Open the saved pages in feedly in chrome
scroll down so they are all there
inspect any element (the top article is a good choice) so it opens the generated html
find the div id="section0_column0" node
right-click & copy it
paste into Notepad++
this html is untidy so carry on...
Do a Regex find & replace
find: (?s)<div id=.+?_main.+?>.+?(<a href=")(.+?)(").+?sans-serif">(.+?)</span>.+?</div>.+?</div>.+?</div>
replace: <div>$1$2$3>$2</a></div> <div> $4<br /> <br /></div>
save the html page.
open it in Chrome
Posted the question in the jquery forum and the solution was rather simple (remove http from attribute string)
line 34 should be
script.setAttribute('src', '//code.jquery.com/jquery-latest.min.js');
So to close the loop - for a full searchable/archived list of links not only by title/url but context also(!) you can:
Follow the instructions in https://github.com/ShockwaveNN/feedly-to-pocket (with the correction suggested by kind stranger jakecigar and you also have to register a pocket app (obtain consumer key) for the ruby script to work)
Export html list from your pocket account
Import pocket list to a Kifi library
and at last feedly-free with my personal search engine
I know I'm a bit late to the party but Ive been hunting around for a few days to find a reasonably simple solution. None of which have been listed clearly or concisely on stack overflow or elsewhere on the web. I have in fact found a much easier way to do this.
Use this java script from this Gist just as it instructs https://gist.github.com/ShockwaveNN/a0baf2ca26d1711f10e2 (Note this is referenced above and found through the link #gep shared in step one)
Once the JS as completed running it will download a text file. (It does still run successfully and on large numbers, I just exported almost 2500 articles)
Create a blank test.json in SublimeText.
Copy all entries from your exported text file into this json file
Weirdly it does seem you need to copy and past as I tried just renaming the text file and when I did that I received errors on the next step
Make sure you are signed into pocket
Go here: https://getpocket.com/import/springpad
Select your newly created test.json
Upload
Note: On large uploads the import page fails to refresh (this did not seem to be an issue as all my articles did make it into my account)
This allows you to directly upload json into your pocket account. Thus no more messing around with random supposed other fixes. I hope this make it a lot easier for everyone in the future.

Javascript verify image without file type

The question may look simple, but I have found the answer to be very elusive. I have a shoutcast server broadcasting two images, and they can only be retrieved from certain urls, which don't contain the file's type. What I'm trying to do is get the album art that is being broadcast on a constant url. If that url doesn't have an image that can used, switch to the other url. The code I have written is on JS fiddle. And here's the trouble spot:
try {
console.log("testing...");
if (img2.height > 0) {
//I have to use something other than the image height, because
//that's already determined by CSS
//thus always setting clear to true,
//regardless of the image.
console.log("cleared [true]");
clear = true;
} else {
console.log("cleared [false]");
clear = false;
}
One solution I thought might work is the user's browser throws up an error in the console
"Resource interpreted as Image but transferred with MIME type text/plain:" but from what I gathered, javascript can't access that kind of information. I've also tried numerous comparisons in the if statement, but with no luck, they always give the same results, regardless of the image. So I've hit a roadblock and don't really know what I need, I hate leaving this so open-ended, but it's really the best I've got. I've got the server running two music tracks and their album art, I'll let you guys play around with it.
Use the onerror event, like:
img2.onerror = function(){
alert('see');
}
http://jsfiddle.net/364F8/1/
I'm not rewriting your code, but you should 'see' how it works with the example.

JavaScript to Replace One QuickTime movie with Another

I am very new to javascript so bear with me:
I am trying to replace one quicktime movie with another one, so far i have used this code from apple and it works great
you can see my efforts here: http://www.centurysunstudios.co.uk/test/
please look at the source code (i tried to past the code here but would not let me for some reason; said i could only post one url as a new user? )
the problem is that the replace method apple use works in every browser (on osx and windows) apart from IE. In IE the movies do not replace and i get this message;
Error: document.movie is null or not an object
Apple seem to not have a solution and my javascript is limited
Any help would be greatly appriciated
Thanks
Try this:
<script>
function changeMovie(movieURL){
var embeds = document.getElementsByTagName("embed");
for(var i=0;i<embeds.length;i++){
if(embeds[i].getAttribute("name")=="movie"){
embeds[i].SetURL(movieURL);
}
}
}
</script>
L(o2)

Categories