// ==UserScript== // @name BBC iPlayer video download // @namespace http://andrealazzarotto.com/ // @include http://www.bbc.co.uk/iplayer/episode/* // @include http://www.bbc.co.uk/programmes/* // @version 2.1 // @description This script allows to save videos from BBC iPlayer. // @copyright 2015+, Andrea Lazzarotto - GPLv3 License // @require http://code.jquery.com/jquery-latest.min.js // @grant GM_xmlhttpRequest // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html // @downloadURL none // ==/UserScript== get_title = function() { var title = $('meta[property="og:title"]').attr('content') || 'output'; return title.replace(/\W+/g, '_'); } appendURL = function(element, url) { element.after('
'); $('#direct-link').css({ 'padding': '.75em', 'margin': '25px auto', 'width': $('#player-outer-outer').width(), 'border': '1px solid #444', 'color': 'white', 'font-family': 'sans-serif', 'box-sizing': 'border-box' }).append('To record the video, use avconv
with the following command line:
avconv -i "' + url + '" -codec copy -qscale 0 ' + get_title() + '.mp4' + '
Alternatively, you may also try to record the M3U8 stream URL with VLC.
'); $('#direct-link pre, #direct-link code').css({ 'white-space': 'normal', 'word-break': 'break-word', 'font-size': $('#direct-link p').css('font-size'), 'margin': '.75em 0', 'padding': '.75em', 'background-color': '#444' }); $('#direct-link code').css('padding','.25em'); $('#direct-link p:last-child').css('margin-bottom', '0'); } get_biggest = function(dict) { var s = 0; var o = null; for(var key in dict) { key = parseInt(key) || 0; if (key > s) { s = key; o = dict[key]; } } return {'size': s, 'object': o}; } handle_pid = function(vpid, selector){ var config_url = 'http://www.bbc.co.uk/iplayer/config/windows-phone'; // figure out the mediaselector URL $.getJSON(config_url, function(data) { var selector_mobile = data['mediaselector'].replace('{vpid}', vpid); var selector_pc = selector_mobile.replace(/mobile-.*vpid/, 'pc/vpid'); // get mobile data GM_xmlhttpRequest({ method: 'GET', url: selector_mobile, onload: function(responseDetails) { var r = responseDetails.responseText; var doc = $.parseXML(r); var $xml = $(doc); var media = {}; $xml.find('media[kind^="video"]').each(function() { var bitrate = $(this).attr('bitrate'); var href = $(this).find('connection').attr('href'); media[bitrate] = href; }); var m3u8_url = get_biggest(media); console.log("M3U8_URL: " + m3u8_url['object']); // get desktop data for higher quality GM_xmlhttpRequest({ method: 'GET', url: selector_pc, onload: function(responseDetails) { var r = responseDetails.responseText; var doc = $.parseXML(r); var $xml = $(doc); var media = {}; $xml.find('media[kind^="video"]').each(function() { var bitrate = $(this).attr('bitrate'); var identifier = $(this).find('connection[application="ondemand"], ' + 'connection[application*="/e3"]').attr('identifier'); if(identifier) media[bitrate] = identifier; }); var high_quality = get_biggest(media); console.log("HIGH_QUALITY: " + high_quality['object']); // compose the M3U8 stream URL GM_xmlhttpRequest({ method: 'GET', url: m3u8_url['object'], onload: function(responseDetails) { var r = responseDetails.responseText; var urls = r.split('\n').slice(1); var final_url = urls[1]; // fix the final url var old_pieces = final_url.split(','); var pieces = [old_pieces[0], old_pieces[1], old_pieces[old_pieces.length-1]]; var p = 1; var high_quality_piece = high_quality['object'].replace('.mp4','') .replace('secure_auth/','').split('/').slice(1).join('/'); var new_p = pieces[p].split('/').slice(0,2).join('/') + '/' + high_quality_piece; pieces[p] = new_p; final_url = pieces.join(','); // output the M3U8 URL appendURL($(selector), final_url); } }); } }); } }); }); // getJSON } $(document).ready(function(){ var isProgramme = !!unsafeWindow.bbcProgrammes; if (isProgramme) { var clipid = location.href.split("/")[4]; $.getJSON('http://www.bbc.co.uk/programmes/' + clipid + '/playlist.json', function(data) { var vpid = data.defaultAvailableVersion.pid; console.log("VPID: " + vpid.toString()); handle_pid(vpid, '.island .cf.component'); }); } else { var spid = $('script:contains("mediator.bind")').html(); var vpid = spid.split('vpid')[1].split('"')[2]; handle_pid(vpid, '#player-outer-outer'); } }); // $(document).ready.ready