Javascript get updated link in real time - javascript

I'm new to javascript and I've created a kinda successful extension on chrome for dubtrack I've been trying to figure out for quite awhile how to make my injected script run in real time and grab the latest youtube music video url any help would be much appreciated my extension is very basic and it's not for profit I just made it to play around with javascript and jquery.
Here's the section of code that I'd like to have function in real time.
$('#grab').click(function() {
function getId(url) {
var regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
var match = url.match(regExp);
if (match && match[2].length == 11) {
return match[2];
} else {
return 'error';
}
}
src = $('iframe').attr('src');
setInterval(function() {
src = $('iframe').attr('src');
}, 10000);
window.open('http://youtubeinmp3.com/fetch/?video=http://www.youtube.com/watch?v=' + getId(src), '_blank');
});
Relevant links
GitHub
Chrome Extension
Thank you for taking the time to read my question.

You're bad at explaining (and might want to edit the question to reflect what you want), but basically the problem is this:
You have a YouTube embed in the page, with a particular video ID in src.
When the video changes, that happens without updating the src (by using YT embed API).
Therefore, if you try to grab just the src, it's not the latest video but the first you loaded.
As an extension, I see two ways of trying to solve it:
You could try to initialize the YT API yourself to get a player reference. I don't know if it will break the code of Dubtrack.
You could inject a script in the iframe as well that would somehow extract the video being played in a way other than relying on src.
It's an open problem how to solve it, and the fact that you're basically providing "just" a bookmarklet may be an obstacle.

Related

Change youtube video ID without page reloading

This question is about scripting the main youtube site, client side from javascript.
While it looks easy as a click, I found no way to change the current video by a new non in context video ID without reloading.
This seems to be related with the polymer library in use, with a lot of shadow dom and some special behavior.
Here is the context: I am making for my own use a bookmarklet that load videos from the reddit json api, wich supports CORS calls.
So far so good, I can load many videos, image previews and links into the youtube sidebar, with this simple enough handcrafted script.
Bookmarklet to call the script:
javascript:void%20function(){target=document.getElementsByTagName(%22script%22)[0],inj=document.createElement(%22script%22),inj.src=%22https://webdev23.github.io/reddube/reddube.js%22,target.appendChild(inj)}();
This bookmarklet is loading into the DOM a js file, that is parsing the json api to get what I need.
Here is the content of the called file:
var reds = ["/r/videos","/r/unknownvideos","/r/DeepIntoYouTube","/r/newsreels","/r/fullmoviesonyoutube","/r/SF_Videos","/r/classicfilms","/r/Documentaries","/r/artdocumentaries","/r/ShowsonYT","/r/YTPL","/r/NotTimAndEric","/r/youtubehaiku","/r/PlayItAgainSam","/r/ObscureMedia","/r/360video","/r/AccidentalComedy","/r/amibeingdetained","/r/ArtisanVideos","/r/AwfulCommercials","/r/bestofworldstar","/r/cringe","/r/CommercialCuts","/r/contagiouslaughter","/r/cookingvideos","/r/curiousvideos","/r/deepintoyoutube","/r/documentaries","/r/educativevideos","/r/FastWorkers","/r/fightporn","/r/FuckingWithNature","/r/fullmoviesonyoutube","/r/happycrowds/","/r/idiotsfightingthings","/r/lectures","/r/mealtimevideos","/r/motivationvideos","/r/ObscureMedia","/r/playitagainsam","/r/Prematurecelebration","/r/PublicFreakout","/r/Roadcam","/r/streetfights","/r/sweetjustice","/r/TheWayWeWereOnVideo","/r/trailers","/r/UnexpectedThugLife","/r/videoporn","/r/vids","/r/vines","/r/virtualfreakout","/r/woahtube","/r/listentothis/","/r/Tekno/","/r/reggae/","/r/RootsReggae","r/ska","/r/dub","/r/hip_hop","/r/treemusic/","/r/stonerrock/","/r/frenchrap/","/r/trance/","/r/minimal/"]
var rview = ["","/new/","/rising/","/controversial/","/top/"]
related.innerHTML = "<div style='filter: sepia(38%) invert(100%) saturate(100%) brightness(1) grayscale(0%) hue-rotate(360deg) contrast(100%)'><span id='subR' data-ccc='25' style='color:white;background:#141e1b;font-size:1.44em;width:20px'></span><input type='range' value='0' max='64' id ='redR' style='float:right;width:230px' onchange='redList.innerHTML=\"\";redd(this.value)'><br><span onclick='redList.innerHTML=\"\";' style='float:right;margin:3px 0 0 0'><button id='rflt' data-filter='0' onclick='this.dataset.filter=0;redd(redR.value)'>hot</button><button onclick='rflt.dataset.filter=1;redd(redR.value)'>new</button><button onclick='rflt.dataset.filter=2;redd(redR.value)'>rising</button><button onclick='rflt.dataset.filter=3;redd(redR.value)'>controversial</button><button onclick='rflt.dataset.filter=4;redd(redR.value)'>top</button></span><hr /><hr /><hr /><hr /><hr /><tr><br></div><div id='redList'>"
function redd(it){
console.log(it)
console.log(reds[1])
subR.innerHTML = reds[it]
xhr = new XMLHttpRequest
xhr.open("GET","https://www.reddit.com"+reds[it]+rview[rflt.dataset.filter]+".json?limit=200",true)
xhr.send(null)
xhr.onreadystatechange = function() {
if (xhr.readyState === xhr.DONE) {
if(this.status === 200) {
vids = JSON.parse(xhr.responseText)
cc = subR.dataset.ccc
for (var j=0;j<=cc;j++){
try{
var rt = vids['data']['children'][j]['data']['title'],
rl = vids['data']['children'][j]['data']['url'],
rp = vids['data']['children'][j]['data']['secure_media']['oembed']['thumbnail_url'],
rr = vids['data']['children'][j]['data']['permalink']
redList.innerHTML += "<td><a href='"+rl+"'><img style='width:150px;height:auto;max-width:120px' src='"+rp+"'></img></a><span style='max-width:68%;float:right;text-align:center;font-size:1.23em'><a class='yt-simple-endpoint style-scope ytd-compact-video-renderer' style='text-decoration:bold;font-size:1.23em;text-align:left;min-width:260px' href='"+rl+"'>"+rt+"</a><a target='blank' style='text-decoration:bold;color:black;float:right' href='https://www.reddit.com"+rr+"'>⮊</a></span></td><br>"
}catch(e){console.log(e)}
}
}
}
}
}
related.innerHTML += "</tr><button onclick='redList.innerHTML=\"\";redd(redR.value)'>Load more</button>"
redd(0)
window.onscroll = function() {
var d = document.documentElement,
offset = d.scrollTop + window.innerHeight,
height = d.offsetHeight
if (offset >= '2000' && offset <= '2300') {
subR.dataset.ccc = 25
}
if (offset >= '2000' && offset <= '2100') {
subR.dataset.ccc = 50
}
if (offset >= '3400' && offset <= '3500') {
subR.dataset.ccc = 100
}
if (offset >= '5400' && offset <= '5500') {
subR.dataset.ccc = 150
}
if (offset >= '7400' && offset <= '7500') {
subR.dataset.ccc = 200
}
}
At this stage, clicking a link is just reloading the page.
I tried many things, changing the content of elements, try to alter the "next" recommended video.
Also creating a link in the DOM, isn't working, it is reloading.
Here is the problem in a simple way:
Let's say you are in this yt page https://www.youtube.com/watch?v=YgGzAKP_HuM
From the console, how to load this non related id -q7ZVXOU3kM
into the page, just like a link click on the recommendation sidebar?
The following is NOT working: Visibility monitor is not attached
xhr = new XMLHttpRequest
xhr.open("GET","https://www.youtube.com/watch?v=-q7ZVXOU3kM",true)
xhr.send(null)
document.body.innerHTML = xhr
18 OF MARCH 2018: END OF BOUNTY: QUESTION UNRESOLVED!!!
This is a fairly complex stuff.
The dom content is constantly changing at every reload, and it include recommended video id into the changing scripts. This id's only are allowed to use the ajax capabilities.
This recommendation are changing at any reload, but they are coming back in loop.
I am building a tool to deeply analyse differences, and i found many interesting things, much more that I was searching.
This topic isn't close!
It's not about the destination, it's about the journey.
Despite the videoId being YgGzAKP_HuMif you inspect the <video> you will see something like that:
<video class="video-stream html5-main-video" src="blob:https://www.youtube.com/8e1ef216-1901-ec44-9b76-ea8276e368c6"></video>
You need to find how youtube create their Blob from a videoId and change the src of the player if you want to avoid reloading the page.
But maybe for your project you should think about using the IFrame Player API. It does exactly what you want. And if you want to stay on youtube.com you can replace the youtube original player by an iframe in the DOM.
Good Luck!
it appears that there is no (public) api for the player on youtube :/
but there is one for the iframe youtube player - there you can just call
player.loadVideoById("Vw4KVoEVcr0", 0, "default");
for details see https://developers.google.com/youtube/iframe_api_reference#loadVideoById
That is a quick example I found where you see it in action: http://jsfiddle.net/QtBlueWaffle/8bpQ8/1/
If you really want to directly modify youtube you probably have to dig around in the obfuscated code :/ I tried to find it... but it's obfuscated so you can't easily find it. And even if you find it it will be something like _yt_player.h.xx.xy.h(). Also whenever it will be generated new (and maybe even it is even different for countries... ) your code may break.
Also, it appears to have nothing to do with polymer as there is a player element but it does not have a function to change the video. Apparently, it is only to place the player... control still resides within the js function.
I'm sorry to not have any better news - maybe someone else knows more.
Trying to find a hidden YouTube API is incredibly difficult and it's likely that the next tweak Google makes to YouTube will break your bookmarklet and you'd be back where you started. I think you should take another route altogether. Google provides an API to create, delete, and otherwise manipulate YouTube playlists here: https://developers.google.com/youtube/v3/docs/playlists.
If you’ve never used YouTube API before, see here: https://developers.google.com/youtube/v3/getting-started
Then, (finally!) you can write some JavaScript that creates YouTube playlists from reddit at your command.

Will this hash code change the URL location on randomize?

still practicing javascript.
Here is a JSBIN of a site that I have made that I can't seem to figure out how to make it so the URL will change once the video is clicked or randomized.
(page load/refresh and click both trigger this)
http://jsbin.com/vesebu/1/edit?html,js,output
The page randomizes on load and page click with an array of videos.
What I am trying to figure out is how to change the URL by appending an ID to the end of it. ie: mysite.com/6530 <-- last four digits representing the ID of the video. This will make the site shareable and is what I am trying to figure out how people are able to do this!
I have tried reading documentation on history.js, html5 pushstate as well as window.location hash and nothing seems to work.
M = function(d) {
function a() {
var a;
a = window.location.hash;
/^#\d+$/.test(a) && (window.location.href = "/" + a.slice(1));
/^#!\d+$/.test(a) && (window.location.href = "/" + a.slice(2));
f
}
y(a, d);
return a
}(n);
I was suggested this code by a friend but can't seem to make sense of it, especially with the jsbin I have. I'm completely lost here on how to do this, and have really tried reading up on it.
any help at all is definitely appreciated!
Thanks guys
Your hashes may be like this:
#/2134/23423/
#2134/23423/
result:
windows.location = /2134/23423/;
then do something else.......
Hope it can help you ~

Text to speech using javascript and translate_tts

I have been trying to get my webpage to play up what it says in a text box when the user click on a link, but so far I haven't manage. I have tried with
function listen(){
var sound = new Audio();
sound.src = "http://translate.google.com/translate_tts?ie=UTF-8&tl=sv&q=Testar";
sound.play();
alert(":D");
return false;
}
and
function listen(){
var sound = document.createElement("audio");
sound.setAttribute("src","http://translate.google.com/translate_tts?tl=sv&q=Testar");
sound.load();
sound.play();
alert(":D");
return false;
}
I have tried adding ie=UTF-8 to the link, and tried both with and without sound.play(); but nothing have worked. I get smiley face from the alert so I know the function runs. Can someone please help me get this to work.
EDIT: I did a work around by using and iframe which I hide by using display: none; and then simply using javascript to change the src, not the best solution but it works... for now.
This is an easy way to do it :
var sound = new Audio("http://translate.google.com/translate_tts?tl=sv&q=Testar");
sound.play();
Now it's a bit more complicated, but still possible:
you need set up an user-agent string like a common browser and, more difficult, you also must provide a token into the GET request.
Some people managed to extract the token algorithm from the js code of the page, but it's quite a long work and at any time the algorithm changes you need to start again the reverse engineering of the cryptic code.
So it's much easier access to a particular url from the same site that generates an XHR that shows the token you need.
A simple script with phantomjs and grep will do the job for you, details here:
https://stackoverflow.com/a/37221340/6332793

How can I get the embed id for Slideshare from the complete URL?

I want to let user add Slideshare presentation and Youtube video on my Website. I don't want them to go through the trouble of finding the embeded code, I want to generate it myself so I determine the size and protocole and they just have to copy the URL they see in the address bar.
It was easy to do with Youtube, I just had to extract the video id. It doesn't seem that easy with Slideshare since the full URL doesn't contain the id that is used when embedding the presentation.
So basically, I want to know how to go from this
http://www.slideshare.net/guest196e23/joel-spolsky-100-things-keynote
to
http://www.slideshare.net/slideshow/embed_code/4053571
Or even more precisely, from "guest196e23/joel-spolsky-100-things-keynote" to "4053571"
I would like a client-side (javascript) solution.
Thanks for your help!
You can easily achieve that using Node.js and JSDOM
jsdom.env(
"http://www.slideshare.net/DonaldDerek/build-your-own-raspitv-with-nodejs-socketio",
["http://code.jquery.com/jquery.js"],
function (errors, window) {
var $ = window.$ ,
presentation = $(".twitter_player").attr('value')
if(presentation === undefined){
res.json({error:true})
}
else{
res.json({presentation_embed:presentation, error:false})
}
}
)
Then simply catch the response inside your AJAX Callback.

JS .play() on iPad plays wrong file...suggestions?

So, I am building a web app that has a div with text that changes on various user actions (it's stepping through an array of pieces of text). I'm trying to add audio to it, so I made another array with the sound files in the appropriate positions:
var phrases=['Please hand me the awl.','etc1','etc2','etc3'];
var phrasesAudio=['awl.mp3','etc1.mp3','etc2.mp3','etc3.mp3'];
And on each action completion, a 'counter' variable in incremented, and each array looks for the object at that counter
var audio = document.createElement("audio"),
canPlayMP3 = (typeof audio.canPlayType === "function" &&
audio.canPlayType("audio/mpeg") !== "");
function onAction(){
correct++;
document.getElementById('speech').innerHTML=phrases[correct];
if(canPlayMP3){
snd = new Audio(phrasesAudio[correct]);
}
else{
snd = new Audio(phrasesAudioOgg[correct]);
}
snd.play();
}
(the text replaces a div's HTML and I use .play() for the audio object)...usually works okay (and ALWAYS does in a 'real' browser), but on the iPad (the actual target device) after a few successful iterations, the TEXT continues to progress accurately, but the AUDIO will hiccup and repeat a sound file one or more times. I added some logging and looking there it reports that it's playing screw.mp3 (just an example, no particular file is more or less error prone), but in actuality it plays screwdriver.mp3 (the prior file, if there is an error, the audio always LAGS, never LEADS)...because of this I am thinking that the problem is with my use of .play()...so I tried setting snd=null; between each sound, but nothing changed...Any suggestions for how to proceed? This is my first use of audio elements so any advice is appreciated. Thanks.
edit: I've also tried setting the files with snd.src (based on https://wiki.mozilla.org/Audio_Data_API) and this caused no audio to play
for iPad you need to call snd.load() before snd.play() - otherwise you get "odd" behaviour...
see for some insight:
http://jnjnjn.com/187/playing-audio-on-the-ipad-with-html5-and-javascript/
Autoplay audio files on an iPad with HTML5
EDIT - as per comment from the OP:
Here https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox you can find a tip on halting a currently playing piece of media with
var mediaElement = document.getElementById("myMediaElementID");
mediaElement.pause();
mediaElement.src = "";
and, following that with setting the correct src, load(), play() works great

Categories

Resources