BBC iPlayer video download

This script allows to save videos from BBC iPlayer.

目前為 2015-02-20 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name BBC iPlayer video download
  3. // @namespace http://andrealazzarotto.com/
  4. // @include http://www.bbc.co.uk/iplayer/episode/*
  5. // @version 1.0
  6. // @description This script allows to save videos from BBC iPlayer.
  7. // @copyright 2015+, Andrea Lazzarotto - GPLv3 License
  8. // @require http://code.jquery.com/jquery-latest.min.js
  9. // @grant GM_xmlhttpRequest
  10. // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
  11. // ==/UserScript==
  12.  
  13. get_title = function() {
  14. var title = $('meta[property="og:title"').attr('content') || 'output';
  15. return title.replace(/\W+/g, '_');
  16. }
  17.  
  18. appendURL = function(element, url) {
  19. element.after('<div id="direct-link"></div>');
  20. $('#direct-link').css({
  21. 'padding': '.75em',
  22. 'margin': '25px auto',
  23. 'width': $('#player-outer-outer').width(),
  24. 'border': '1px solid #444',
  25. 'color': 'white',
  26. 'font-family': 'sans-serif',
  27. 'box-sizing': 'border-box'
  28. }).append('<p>To record the video, use <code>avconv</code> with the following command line:</p>' +
  29. '<pre>avconv -i "' + url + '" -codec copy -qscale 0 ' + get_title() + '.mp4</pre>' +
  30. '<p>Alternatively, you may also try to record the M3U8 stream URL with VLC.</p>');
  31. $('#direct-link pre, #direct-link code').css({
  32. 'white-space': 'normal',
  33. 'word-break': 'break-word',
  34. 'font-size': '1.15em',
  35. 'margin': '.75em 0',
  36. 'padding': '.75em',
  37. 'background-color': '#444'
  38. });
  39. $('#direct-link code').css('padding','.25em');
  40. }
  41.  
  42. get_biggest = function(dict) {
  43. var s = 0;
  44. var o = null;
  45. for(var key in dict) {
  46. key = parseInt(key) || 0;
  47. if (key > s) {
  48. s = key;
  49. o = dict[key];
  50. }
  51. }
  52. return {'size': s, 'object': o};
  53. }
  54.  
  55. $(document).ready(function(){
  56. var button = $('button[data-download-sd^="bbc-ipd:download/"]');
  57. var spid = $('script:contains("mediator.bind")').html();
  58. var vpid = spid.split('vpid')[1].split('"')[2];
  59. var config_url = 'http://www.bbc.co.uk/iplayer/config/windows-phone';
  60. // figure out the mediaselector URL
  61. $.getJSON(config_url, function(data) {
  62. var selector_mobile = data['mediaselector'].replace('{vpid}', vpid);
  63. var selector_pc = selector_mobile.replace(/mobile-.*vpid/, 'pc/vpid');
  64. // get mobile data
  65. GM_xmlhttpRequest({
  66. method: 'GET',
  67. url: selector_mobile,
  68. onload: function(responseDetails) {
  69. var r = responseDetails.responseText;
  70. var doc = $.parseXML(r);
  71. var $xml = $(doc);
  72. var media = {};
  73. $xml.find('media[kind^="video"]').each(function() {
  74. var bitrate = $(this).attr('bitrate');
  75. var href = $(this).find('connection').attr('href');
  76. media[bitrate] = href;
  77. });
  78. var m3u8_url = get_biggest(media);
  79. // get desktop data for higher quality
  80. GM_xmlhttpRequest({
  81. method: 'GET',
  82. url: selector_pc,
  83. onload: function(responseDetails) {
  84. var r = responseDetails.responseText;
  85. var doc = $.parseXML(r);
  86. var $xml = $(doc);
  87. var media = {};
  88. $xml.find('media[kind^="video"]').each(function() {
  89. var bitrate = $(this).attr('bitrate');
  90. var identifier = $(this).find('connection[application="ondemand"]').attr('identifier');
  91. if(identifier)
  92. media[bitrate] = identifier;
  93. });
  94. var high_quality = get_biggest(media);
  95. // compose the M3U8 stream URL
  96. GM_xmlhttpRequest({
  97. method: 'GET',
  98. url: m3u8_url['object'],
  99. onload: function(responseDetails) {
  100. var r = responseDetails.responseText;
  101. var urls = r.split('\n').slice(1);
  102. var final_url = urls[1];
  103. // fix the final url
  104. var old_pieces = final_url.split(',');
  105. var pieces = [old_pieces[0], old_pieces[1], old_pieces[old_pieces.length-1]];
  106. var p = 1;
  107. var high_quality_piece = high_quality['object'].replace('.mp4','').split('/').slice(1).join('/');
  108. var new_p = pieces[p].split('/').slice(0,2).join('/') + '/' + high_quality_piece;
  109. pieces[p] = new_p;
  110. final_url = pieces.join(',');
  111. // output the M3U8 URL
  112. appendURL($('#player-outer-outer'), final_url);
  113. }
  114. });
  115. }
  116. });
  117. }
  118. });
  119. }); // getJSON
  120. }); // $(document).ready.ready