2

I have this code, it’s a bookmarklet:

javascript:(function(e,a,g,h,f,c,b,d){if(!(f=e.jQuery)||g>f.fn.jquery||h(f)){c=a.createElement("script");c.type="text/javascript";c.src="cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js";c.onload=c.onreadystatechange=function(){if(!b&&(!(d=this.readyState)||d=="loaded"||d=="complete")){h((f=e.jQuery).noConflict(1),b=1);f(c).remove()}};a.documentElement.childNodes[0].appendChild(c)}})(window,document,"3.4.1",function($,L){var url1 = "download-video-youtube1.p.rapidapi.com/mp3/";var url2 = window.location.href.substring(32);var url3 = url1 + url2;var settings = { "url": url3 , "method": "GET", "headers": {"x-rapidapi-host": "download-video-youtube1.p.rapidapi.com","x-rapidapi-key": "[my apikey here]" } }; $.ajax(settings).done(function(response){ window.location.href = "https://" + response.vidInfo[0].dloadUrl;});});

It works great on firefox and chrome but there is no way it works with ios safari or ios shortcut or chrome on android.

It checks whether there is a specific version of jquery, if not it appends it in the DOM and them runs an api request and returns the Mp3’s download link of any video of youtube.

It’s my third and last question here since I received no answer so far. I know I won’t this time either, never mind i keep it here as a diary.

Good bye

1 Answers1

0

Not sure what could be the issue, the code looks ok (as I have reverse-engineered). If you created the bookmarklet, please include the full source code.

  • Maybe you need to include the protocol in the script url?
  • Also, make sure the version of jQuery is compatible with your Safari/Android browser.

Note: If you want, you can throw jQuery in the trash and use promises. Take a look at Fetch API.

(function() {
  let script = document.createElement("script");
  script.type = "text/javascript";
  script.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js";
  script.onload = script.onreadystatechange = function(e) {
    $.ajax({
      "url": "download-video-youtube1.p.rapidapi.com/mp3/" + window.location.href.substring(32),
      "method": "GET",
      "headers": {
        "x-rapidapi-host": "download-video-youtube1.p.rapidapi.com",
        "x-rapidapi-key": "[my apikey here]"
      }
    }).done(function(response) {
      window.location.href = "https://" + response.vidInfo[0].dloadUrl;
    });
  };
  document.documentElement.childNodes[0].appendChild(script);
})();

Re-minified using javascript-minifier.com:

javascript:!function(){let e=document.createElement("script");e.type="text/javascript",e.src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js",e.onload=e.onreadystatechange=function(e){$.ajax({url:"download-video-youtube1.p.rapidapi.com/mp3/"+window.location.href.substring(32),method:"GET",headers:{"x-rapidapi-host":"download-video-youtube1.p.rapidapi.com","x-rapidapi-key":"[my apikey here]"}}).done(function(e){window.location.href="https://"+e.vidInfo[0].dloadUrl})},document.documentElement.childNodes[0].appendChild(e)}();

Using the fetch API

It's ~17% longer (after minification), but does not rely on jQuery. It also features a YouTube video ID extraction function, so it is more robust.

The script below is a UserScript that can be used with Greasemonkey, Tampermonkey, or Violentmonkey.

// ==UserScript==
// @name         YouTube MP3
// @namespace    com.youtube.mp3
// @version      1.0.0
// @description  Parse the YouTube video ID and request the MP3 version.
// @author       Mr. Polywhirl
// @match        https://www.youtube.com/*
// @match        https://youtube.com/*
// @match        https://youtu.be/*
// @grant        GM_log
// ==/UserScript==
(function() {
  'use strict';
  // See: https://stackoverflow.com/a/8260383/1762224
  const ytUrlParser = (url) => {
    var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
    var match = url.match(regExp);
    return (match && match[7].length == 11) ? match[7] : false;
  }
  const videoId = ytUrlParser(window.location.href);
  if (videoId) {
    const reqUrl = 'download-video-youtube1.p.rapidapi.com/mp3/' + videoId;
    const reqHead = new Headers();
    reqHead.append('x-rapidapi-host', 'download-video-youtube1.p.rapidapi.com');
    reqHead.append('x-rapidapi-key', '[my apikey here]');
    const reqObj = new Request(reqUrl, {
      method: 'GET',
      headers: reqHead,
      mode: 'cors',
      cache: 'default',
    });
    fetch(reqObj)
      .then(function(response) {
        if (!response.ok) { throw Error(response.statusText); }
        return response;
      })
      .then(response => response.vidInfo[0].dloadUrl)
      .then(url => { window.location.href = "https://" + url })
      .catch(error => console.log(error));
  }
})();

Minified:

javascript:!function(){"use strict";const e=(o=window.location.href,!(!(t=o.match(/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/))||11!=t[7].length)&&t[7]);var o,t;if(e){const o="download-video-youtube1.p.rapidapi.com/mp3/"+e,t=new Headers;t.append("x-rapidapi-host","download-video-youtube1.p.rapidapi.com"),t.append("x-rapidapi-key","[my apikey here]");const a=new Request(o,{method:"GET",headers:t,mode:"cors",cache:"default"});fetch(a).then(function(e){if(!e.ok)throw Error(e.statusText);return e}).then(e=>e.vidInfo[0].dloadUrl).then(e=>{window.location.href="https://"+e}).catch(e=>console.log(e))}}();
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • Thank you a lot! I tried using a minimum version of Jquery and now it works, but only on ios safari...any idea why not in android chrome? I used the jquery version 1.8.0 is it possible that chrome doesn’t support it even if it is much old? Also what do you mean by adding protocol in the script url? I’ll keep in mind your suggestion of using fetch method, i will definitely give it a chance after dealing with this tricky thing! – Franco Polato Feb 17 '20 at 23:07
  • @FrancoPolato Added an example of fetch. It may not be fool-proof, but I do not have a key to test. – Mr. Polywhirl Feb 17 '20 at 23:53
  • Thank you very much!! I really appreciate your commitment! I’m going to study your script to understand this method! – Franco Polato Feb 18 '20 at 12:51