BBC iPlayer video download

This script allows to save videos from BBC iPlayer.

当前为 2015-03-16 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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.0
// @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
// ==/UserScript==

get_title = function() {
	var title = $('meta[property="og:title"]').attr('content') || 'output';
	return title.replace(/\W+/g, '_');
}

appendURL = function(element, url) {
	element.after('<div id="direct-link"></div>');
	$('#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('<p>To record the video, use <code>avconv</code> with the following command line:</p>' + 
			  '<pre>avconv -i "' + url + '" -codec copy -qscale 0 ' + get_title() + '.mp4</pre>' +
			  '<p>Alternatively, you may also try to record the M3U8 stream URL with VLC.</p>');
	$('#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');
}

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);
				
				// 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="a1414/e3"]').attr('identifier');
							if(identifier)
								media[bitrate] = identifier;
						});
						var high_quality = get_biggest(media);
						
						// 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;
								
								console.log(high_quality_piece);
								console.log(new_p);
								
								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;
			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