parent
							
								
									5f699251e9
								
							
						
					
					
						commit
						07cf18b9c5
					
				
					 2 changed files with 147 additions and 4 deletions
				
			
		| 
						 | 
					@ -1,20 +1,23 @@
 | 
				
			||||||
# coding: utf-8
 | 
					# coding: utf-8
 | 
				
			||||||
from __future__ import unicode_literals
 | 
					from __future__ import unicode_literals
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .common import InfoExtractor
 | 
					from .common import InfoExtractor
 | 
				
			||||||
from ..utils import (
 | 
					from ..utils import (
 | 
				
			||||||
 | 
					    determine_ext,
 | 
				
			||||||
    ExtractorError,
 | 
					    ExtractorError,
 | 
				
			||||||
    int_or_none,
 | 
					    int_or_none,
 | 
				
			||||||
    parse_duration,
 | 
					    parse_duration,
 | 
				
			||||||
 | 
					    parse_iso8601,
 | 
				
			||||||
    xpath_element,
 | 
					    xpath_element,
 | 
				
			||||||
    xpath_text,
 | 
					    xpath_text,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BRIE(InfoExtractor):
 | 
					class BRIE(InfoExtractor):
 | 
				
			||||||
    IE_DESC = 'Bayerischer Rundfunk Mediathek'
 | 
					    IE_DESC = 'Bayerischer Rundfunk'
 | 
				
			||||||
    _VALID_URL = r'(?P<base_url>https?://(?:www\.)?br(?:-klassik)?\.de)/(?:[a-z0-9\-_]+/)+(?P<id>[a-z0-9\-_]+)\.html'
 | 
					    _VALID_URL = r'(?P<base_url>https?://(?:www\.)?br(?:-klassik)?\.de)/(?:[a-z0-9\-_]+/)+(?P<id>[a-z0-9\-_]+)\.html'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _TESTS = [
 | 
					    _TESTS = [
 | 
				
			||||||
| 
						 | 
					@ -123,10 +126,10 @@ class BRIE(InfoExtractor):
 | 
				
			||||||
        for asset in assets.findall('asset'):
 | 
					        for asset in assets.findall('asset'):
 | 
				
			||||||
            format_url = xpath_text(asset, ['downloadUrl', 'url'])
 | 
					            format_url = xpath_text(asset, ['downloadUrl', 'url'])
 | 
				
			||||||
            asset_type = asset.get('type')
 | 
					            asset_type = asset.get('type')
 | 
				
			||||||
            if asset_type == 'HDS':
 | 
					            if asset_type.startswith('HDS'):
 | 
				
			||||||
                formats.extend(self._extract_f4m_formats(
 | 
					                formats.extend(self._extract_f4m_formats(
 | 
				
			||||||
                    format_url + '?hdcore=3.2.0', media_id, f4m_id='hds', fatal=False))
 | 
					                    format_url + '?hdcore=3.2.0', media_id, f4m_id='hds', fatal=False))
 | 
				
			||||||
            elif asset_type == 'HLS':
 | 
					            elif asset_type.startswith('HLS'):
 | 
				
			||||||
                formats.extend(self._extract_m3u8_formats(
 | 
					                formats.extend(self._extract_m3u8_formats(
 | 
				
			||||||
                    format_url, media_id, 'mp4', 'm3u8_native', m3u8_id='hds', fatal=False))
 | 
					                    format_url, media_id, 'mp4', 'm3u8_native', m3u8_id='hds', fatal=False))
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
| 
						 | 
					@ -169,3 +172,140 @@ class BRIE(InfoExtractor):
 | 
				
			||||||
        } for variant in variants.findall('variant') if xpath_text(variant, 'url')]
 | 
					        } for variant in variants.findall('variant') if xpath_text(variant, 'url')]
 | 
				
			||||||
        thumbnails.sort(key=lambda x: x['width'] * x['height'], reverse=True)
 | 
					        thumbnails.sort(key=lambda x: x['width'] * x['height'], reverse=True)
 | 
				
			||||||
        return thumbnails
 | 
					        return thumbnails
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BRMediathekIE(InfoExtractor):
 | 
				
			||||||
 | 
					    IE_DESC = 'Bayerischer Rundfunk Mediathek'
 | 
				
			||||||
 | 
					    _VALID_URL = r'https?://(?:www\.)?br\.de/mediathek/video/[^/?&#]*?-(?P<id>av:[0-9a-f]{24})'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _TESTS = [{
 | 
				
			||||||
 | 
					        'url': 'https://www.br.de/mediathek/video/gesundheit-die-sendung-vom-28112017-av:5a1e6a6e8fce6d001871cc8e',
 | 
				
			||||||
 | 
					        'md5': 'fdc3d485835966d1622587d08ba632ec',
 | 
				
			||||||
 | 
					        'info_dict': {
 | 
				
			||||||
 | 
					            'id': 'av:5a1e6a6e8fce6d001871cc8e',
 | 
				
			||||||
 | 
					            'ext': 'mp4',
 | 
				
			||||||
 | 
					            'title': 'Die Sendung vom 28.11.2017',
 | 
				
			||||||
 | 
					            'description': 'md5:6000cdca5912ab2277e5b7339f201ccc',
 | 
				
			||||||
 | 
					            'timestamp': 1511942766,
 | 
				
			||||||
 | 
					            'upload_date': '20171129',
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _real_extract(self, url):
 | 
				
			||||||
 | 
					        clip_id = self._match_id(url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        clip = self._download_json(
 | 
				
			||||||
 | 
					            'https://proxy-base.master.mango.express/graphql',
 | 
				
			||||||
 | 
					            clip_id, data=json.dumps({
 | 
				
			||||||
 | 
					                "query": """{
 | 
				
			||||||
 | 
					  viewer {
 | 
				
			||||||
 | 
					    clip(id: "%s") {
 | 
				
			||||||
 | 
					      title
 | 
				
			||||||
 | 
					      description
 | 
				
			||||||
 | 
					      duration
 | 
				
			||||||
 | 
					      createdAt
 | 
				
			||||||
 | 
					      ageRestriction
 | 
				
			||||||
 | 
					      videoFiles {
 | 
				
			||||||
 | 
					        edges {
 | 
				
			||||||
 | 
					          node {
 | 
				
			||||||
 | 
					            publicLocation
 | 
				
			||||||
 | 
					            fileSize
 | 
				
			||||||
 | 
					            videoProfile {
 | 
				
			||||||
 | 
					              width
 | 
				
			||||||
 | 
					              height
 | 
				
			||||||
 | 
					              bitrate
 | 
				
			||||||
 | 
					              encoding
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      captionFiles {
 | 
				
			||||||
 | 
					        edges {
 | 
				
			||||||
 | 
					          node {
 | 
				
			||||||
 | 
					            publicLocation
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      teaserImages {
 | 
				
			||||||
 | 
					        edges {
 | 
				
			||||||
 | 
					          node {
 | 
				
			||||||
 | 
					            imageFiles {
 | 
				
			||||||
 | 
					              edges {
 | 
				
			||||||
 | 
					                node {
 | 
				
			||||||
 | 
					                  publicLocation
 | 
				
			||||||
 | 
					                  width
 | 
				
			||||||
 | 
					                  height
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}""" % clip_id}).encode(), headers={
 | 
				
			||||||
 | 
					                'Content-Type': 'application/json',
 | 
				
			||||||
 | 
					            })['data']['viewer']['clip']
 | 
				
			||||||
 | 
					        title = clip['title']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        formats = []
 | 
				
			||||||
 | 
					        for edge in clip.get('videoFiles', {}).get('edges', []):
 | 
				
			||||||
 | 
					            node = edge.get('node', {})
 | 
				
			||||||
 | 
					            n_url = node.get('publicLocation')
 | 
				
			||||||
 | 
					            if not n_url:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            ext = determine_ext(n_url)
 | 
				
			||||||
 | 
					            if ext == 'm3u8':
 | 
				
			||||||
 | 
					                formats.extend(self._extract_m3u8_formats(
 | 
				
			||||||
 | 
					                    n_url, clip_id, 'mp4', 'm3u8_native',
 | 
				
			||||||
 | 
					                    m3u8_id='hls', fatal=False))
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                video_profile = node.get('videoProfile', {})
 | 
				
			||||||
 | 
					                tbr = int_or_none(video_profile.get('bitrate'))
 | 
				
			||||||
 | 
					                format_id = 'http'
 | 
				
			||||||
 | 
					                if tbr:
 | 
				
			||||||
 | 
					                    format_id += '-%d' % tbr
 | 
				
			||||||
 | 
					                formats.append({
 | 
				
			||||||
 | 
					                    'format_id': format_id,
 | 
				
			||||||
 | 
					                    'url': n_url,
 | 
				
			||||||
 | 
					                    'width': int_or_none(video_profile.get('width')),
 | 
				
			||||||
 | 
					                    'height': int_or_none(video_profile.get('height')),
 | 
				
			||||||
 | 
					                    'tbr': tbr,
 | 
				
			||||||
 | 
					                    'filesize': int_or_none(node.get('fileSize')),
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					        self._sort_formats(formats)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        subtitles = {}
 | 
				
			||||||
 | 
					        for edge in clip.get('captionFiles', {}).get('edges', []):
 | 
				
			||||||
 | 
					            node = edge.get('node', {})
 | 
				
			||||||
 | 
					            n_url = node.get('publicLocation')
 | 
				
			||||||
 | 
					            if not n_url:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            subtitles.setdefault('de', []).append({
 | 
				
			||||||
 | 
					                'url': n_url,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        thumbnails = []
 | 
				
			||||||
 | 
					        for edge in clip.get('teaserImages', {}).get('edges', []):
 | 
				
			||||||
 | 
					            for image_edge in edge.get('node', {}).get('imageFiles', {}).get('edges', []):
 | 
				
			||||||
 | 
					                node = image_edge.get('node', {})
 | 
				
			||||||
 | 
					                n_url = node.get('publicLocation')
 | 
				
			||||||
 | 
					                if not n_url:
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                thumbnails.append({
 | 
				
			||||||
 | 
					                    'url': n_url,
 | 
				
			||||||
 | 
					                    'width': int_or_none(node.get('width')),
 | 
				
			||||||
 | 
					                    'height': int_or_none(node.get('height')),
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            'id': clip_id,
 | 
				
			||||||
 | 
					            'title': title,
 | 
				
			||||||
 | 
					            'description': clip.get('description'),
 | 
				
			||||||
 | 
					            'duration': int_or_none(clip.get('duration')),
 | 
				
			||||||
 | 
					            'timestamp': parse_iso8601(clip.get('createdAt')),
 | 
				
			||||||
 | 
					            'age_limit': int_or_none(clip.get('ageRestriction')),
 | 
				
			||||||
 | 
					            'formats': formats,
 | 
				
			||||||
 | 
					            'subtitles': subtitles,
 | 
				
			||||||
 | 
					            'thumbnails': thumbnails,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,7 +127,10 @@ from .bloomberg import BloombergIE
 | 
				
			||||||
from .bokecc import BokeCCIE
 | 
					from .bokecc import BokeCCIE
 | 
				
			||||||
from .bostonglobe import BostonGlobeIE
 | 
					from .bostonglobe import BostonGlobeIE
 | 
				
			||||||
from .bpb import BpbIE
 | 
					from .bpb import BpbIE
 | 
				
			||||||
from .br import BRIE
 | 
					from .br import (
 | 
				
			||||||
 | 
					    BRIE,
 | 
				
			||||||
 | 
					    BRMediathekIE,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from .bravotv import BravoTVIE
 | 
					from .bravotv import BravoTVIE
 | 
				
			||||||
from .breakcom import BreakIE
 | 
					from .breakcom import BreakIE
 | 
				
			||||||
from .brightcove import (
 | 
					from .brightcove import (
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue