[bbc.co.uk] Add support for bbc.co.uk radio programmes (Closes #2184)
authorSergey M. <dstftw@gmail.com>
Sat, 8 Feb 2014 14:55:28 +0000 (21:55 +0700)
committerSergey M. <dstftw@gmail.com>
Sat, 8 Feb 2014 14:55:28 +0000 (21:55 +0700)
youtube_dl/downloader/rtmp.py
youtube_dl/extractor/__init__.py
youtube_dl/extractor/bbccouk.py [new file with mode: 0644]

index b165e396f5f4499bf67874254132b4facdbc78aa..e93c28d6482857d6f84cf3acd6b5b1651168d660 100644 (file)
@@ -87,8 +87,10 @@ class RtmpFD(FileDownloader):
         url = info_dict['url']
         player_url = info_dict.get('player_url', None)
         page_url = info_dict.get('page_url', None)
         url = info_dict['url']
         player_url = info_dict.get('player_url', None)
         page_url = info_dict.get('page_url', None)
+        app = info_dict.get('app', None)
         play_path = info_dict.get('play_path', None)
         tc_url = info_dict.get('tc_url', None)
         play_path = info_dict.get('play_path', None)
         tc_url = info_dict.get('tc_url', None)
+        flash_version = info_dict.get('flash_version', None)
         live = info_dict.get('rtmp_live', False)
         conn = info_dict.get('rtmp_conn', None)
 
         live = info_dict.get('rtmp_live', False)
         conn = info_dict.get('rtmp_conn', None)
 
@@ -111,12 +113,16 @@ class RtmpFD(FileDownloader):
             basic_args += ['--swfVfy', player_url]
         if page_url is not None:
             basic_args += ['--pageUrl', page_url]
             basic_args += ['--swfVfy', player_url]
         if page_url is not None:
             basic_args += ['--pageUrl', page_url]
+        if app is not None:
+            basic_args += ['--app', app]
         if play_path is not None:
             basic_args += ['--playpath', play_path]
         if tc_url is not None:
             basic_args += ['--tcUrl', url]
         if test:
             basic_args += ['--stop', '1']
         if play_path is not None:
             basic_args += ['--playpath', play_path]
         if tc_url is not None:
             basic_args += ['--tcUrl', url]
         if test:
             basic_args += ['--stop', '1']
+        if flash_version is not None:
+            basic_args += ['--flashVer', flash_version]
         if live:
             basic_args += ['--live']
         if conn:
         if live:
             basic_args += ['--live']
         if conn:
index c0a57c73d860d2320ed60126ef69d8a5e1660fec..bc1e57aff10beda5ccb64930a85f06ea3fc7d411 100644 (file)
@@ -15,6 +15,7 @@ from .arte import (
 from .auengine import AUEngineIE
 from .bambuser import BambuserIE, BambuserChannelIE
 from .bandcamp import BandcampIE, BandcampAlbumIE
 from .auengine import AUEngineIE
 from .bambuser import BambuserIE, BambuserChannelIE
 from .bandcamp import BandcampIE, BandcampAlbumIE
+from .bbccouk import BBCCoUkIE
 from .blinkx import BlinkxIE
 from .bliptv import BlipTVIE, BlipTVUserIE
 from .bloomberg import BloombergIE
 from .blinkx import BlinkxIE
 from .bliptv import BlipTVIE, BlipTVUserIE
 from .bloomberg import BloombergIE
diff --git a/youtube_dl/extractor/bbccouk.py b/youtube_dl/extractor/bbccouk.py
new file mode 100644 (file)
index 0000000..43e8ad3
--- /dev/null
@@ -0,0 +1,116 @@
+from __future__ import unicode_literals
+
+import re
+
+from .common import InfoExtractor
+from ..utils import ExtractorError
+
+
+class BBCCoUkIE(InfoExtractor):
+    IE_NAME = 'bbc.co.uk'
+    IE_DESC = 'BBC - iPlayer Radio'
+    _VALID_URL = r'https?://(?:www\.)?bbc\.co\.uk/programmes/(?P<id>[\da-z]{8})'
+
+    _TEST = {
+        'url': 'http://www.bbc.co.uk/programmes/p01q7wz1',
+        'info_dict': {
+            'id': 'p01q7wz4',
+            'ext': 'flv',
+            'title': 'Friction: Blu Mar Ten guest mix: Blu Mar Ten - Guest Mix',
+            'description': 'Blu Mar Ten deliver a Guest Mix for Friction.',
+            'duration': 1936,
+        },
+        'params': {
+            # rtmp download
+            'skip_download': True,
+        }
+    }
+
+    def _real_extract(self, url):
+        mobj = re.match(self._VALID_URL, url)
+        group_id = mobj.group('id')
+
+        playlist = self._download_xml('http://www.bbc.co.uk/iplayer/playlist/%s' % group_id, group_id,
+            'Downloading playlist XML')
+
+        item = playlist.find('./{http://bbc.co.uk/2008/emp/playlist}item')
+        if item is None:
+            no_items = playlist.find('./{http://bbc.co.uk/2008/emp/playlist}noItems')
+            if no_items is not None:
+                reason = no_items.get('reason')
+                if reason == 'preAvailability':
+                    msg = 'Episode %s is not yet available' % group_id
+                elif reason == 'postAvailability':
+                    msg = 'Episode %s is no longer available' % group_id
+                else:
+                    msg = 'Episode %s is not available: %s' % (group_id, reason)
+                raise ExtractorError(msg, expected=True)
+            raise ExtractorError('Failed to extract media for episode %s' % group_id, expected=True)
+
+        title = playlist.find('./{http://bbc.co.uk/2008/emp/playlist}title').text
+        description = playlist.find('./{http://bbc.co.uk/2008/emp/playlist}summary').text
+
+        radio_programme_id = item.get('identifier')
+        duration = int(item.get('duration'))
+
+        media_selection = self._download_xml(
+            'http://open.live.bbc.co.uk/mediaselector/5/select/version/2.0/mediaset/pc/vpid/%s'  % radio_programme_id,
+            radio_programme_id, 'Downloading media selection XML')
+
+        formats = []
+        for media in media_selection.findall('./{http://bbc.co.uk/2008/mp/mediaselection}media'):
+            bitrate = int(media.get('bitrate'))
+            encoding = media.get('encoding')
+            service = media.get('service')
+            connection = media.find('./{http://bbc.co.uk/2008/mp/mediaselection}connection')
+            protocol = connection.get('protocol')
+            priority = connection.get('priority')
+            supplier = connection.get('supplier')
+            if protocol == 'http':
+                href = connection.get('href')
+                # ASX playlist
+                if supplier == 'asx':
+                    asx = self._download_xml(href, radio_programme_id, 'Downloading %s ASX playlist' % service)
+                    for i, ref in enumerate(asx.findall('./Entry/ref')):
+                        formats.append({
+                            'url': ref.get('href'),
+                            'format_id': '%s_ref%s' % (service, i),
+                            'abr': bitrate,
+                            'acodec': encoding,
+                            'preference': priority,
+                        })
+                    continue
+                # Direct link
+                formats.append({
+                    'url': href,
+                    'format_id': service,
+                    'abr': bitrate,
+                    'acodec': encoding,
+                    'preference': priority,
+                })
+            elif protocol == 'rtmp':
+                application = connection.get('application', 'ondemand')
+                auth_string = connection.get('authString')
+                identifier = connection.get('identifier')
+                server = connection.get('server')
+                formats.append({
+                    'url': '%s://%s/%s?%s' % (protocol, server, application, auth_string),
+                    'play_path': identifier,
+                    'app': '%s?%s' % (application, auth_string),
+                    'rtmp_live': False,
+                    'ext': 'flv',
+                    'format_id': service,
+                    'abr': bitrate,
+                    'acodec': encoding,
+                    'preference': priority,
+                })
+
+        self._sort_formats(formats)
+
+        return {
+            'id': radio_programme_id,
+            'title': title,
+            'description': description,
+            'duration': duration,
+            'formats': formats,
+        }
\ No newline at end of file