You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
youtube-dl/youtube_dl/extractor/playsuisse.py

300 lines
6.3 KiB
Python

# coding: utf-8
from __future__ import unicode_literals
import json
from .common import InfoExtractor
from ..utils import std_headers
class PlaySuisseIE(InfoExtractor):
_MEDIA_URL = 'https://4bbepzm4ef.execute-api.eu-central-1.amazonaws.com/prod/graphql'
_VALID_URL = r'https?://(?:www\.)?playsuisse\.ch/watch/(?P<id1>[0-9]+)'
_TESTS = [
{
'url': 'https://www.playsuisse.ch/watch/763211/0',
'md5': '0d716b7a16c3e6ab784ef817ee9a20c1',
'info_dict': {
'id': '763211',
'ext': 'mp4',
'title': 'Wilder S01E01 - Knochen',
'description': 'md5:8ea7a8076ba000cd9e8bc132fd0afdd8'
}
},
{
'url': 'https://www.playsuisse.ch/watch/808675/0',
'md5': '7aa043e69fea5044db2da8bb58bca239',
'info_dict': {
'id': '808675',
'ext': 'mp4',
'title': 'Der Läufer',
'description': 'md5:'
}
},
{
'url': 'https://www.playsuisse.ch/watch/817913/0',
'md5': '50721c46ca0b3a9836eb61ecb0ed7097',
'info_dict': {
'id': '42',
'ext': 'mp4',
'title': 'Nr. 47 S01E01 - Die Einweihungsparty',
'description': 'md5:'
}
}
]
def _get_media_data(self, media_id):
locale = std_headers.get('locale', 'de').strip()
# TODO find out why the locale has no effect in request
response = self._download_json(
self._MEDIA_URL,
media_id,
data=json.dumps({
'operationName': 'AssetWatch',
'query': self._GRAPHQL_QUERY,
'variables': {
"assetId": media_id
}
}).encode('utf-8'),
headers={'Content-Type': 'application/json', 'locale': locale})
return response['data']['asset']
def _real_extract(self, url):
media_id, = self._VALID_URL_RE.match(url).groups()
media_data = self._get_media_data(media_id)
def _get_title(data):
if data.get('seriesName'):
return '{} S{:02}E{:02} - {}'.format(
data['seriesName'],
int(data['seasonNumber']),
int(data['episodeNumber']),
data['name'])
else:
return data['name']
title = _get_title(media_data)
description = media_data['description']
thumbnails = [
{
'id': thumb['id'],
'url': thumb['url']
}
for key, thumb in media_data.items()
if key.startswith('thumbnail') and thumb is not None
]
formats = []
for media in media_data['medias']:
# NOTE subtitle info is included in the m3u8 file, but it's not supported by ytdl
# https://github.com/ytdl-org/youtube-dl/issues/6106
if media['type'] == 'HLS':
formats.extend(self._extract_m3u8_formats(
media['url'],
media_id,
'mp4',
'm3u8_native',
m3u8_id="HLS",
fatal=False))
# NOTE seems to be 404 for all tested media
elif media['type'] == 'DASH' and False:
formats.extend(self._extract_mpd_formats(
media['url'],
media_id,
mpd_id='dash',
fatal=False
))
return {
'id': media_id,
'title': title,
'description': description,
'thumbnails': thumbnails,
'formats': formats,
}
_GRAPHQL_QUERY = '''\
query AssetWatch($assetId: ID!) {
asset(assetId: $assetId) {
...Asset
__typename
}
}
fragment Asset on Asset {
...AssetDetails
episodes {
...AssetDetails
__typename
}
__typename
}
fragment AssetDetails on Asset {
audioLanguages
awards
bu
contentCategories
contentCodes
contentTypes
contractType
countries
creators
creditsTimeInSecs
description
descriptionLong
directors
downloadable
duration
editorialContentCategoriesDatalab {
id
title
__typename
}
editorialContentMetaCategoriesDatalab {
id
title
__typename
}
endDate
episodeNumber
episodesInSequence
externalId
firstEpisodeDuration
id
image16x9 {
...ImageDetails
__typename
}
image2x3 {
...ImageDetails
__typename
}
image16x9WithTitle {
...ImageDetails
__typename
}
image2x3WithTitle {
...ImageDetails
__typename
}
mainCast
name
nextEpisode {
id
episodeNumber
seasonNumber
numberOfEpisodesInSeason
image16x9 {
...ImageDetails
__typename
}
__typename
}
numberOfSeasons
otherKeyPeople
parentalRating
popularity
premium
presenters
primaryLanguage
productionCompanies
productionCountries
provider
ratings
regions
restrictions
seasons {
seasonNumber
assetIds
__typename
}
seasonNumber
seriesId
seriesName
nextEpisode {
...NextEpisodeDetails
__typename
}
parentId
startDate
subtitleLanguages
tagline
targetAudience
themes
thumbnail16x9 {
...ImageDetails
__typename
}
thumbnail2x3 {
...ImageDetails
__typename
}
thumbnail16x9WithTitle {
...ImageDetails
__typename
}
thumbnail2x3WithTitle {
...ImageDetails
__typename
}
type
writers
year
medias {
...MediaDetails
__typename
}
trailerMedias {
...MediaDetails
__typename
}
sponsors {
...SponsorDetails
__typename
}
sponsorEndDate
__typename
}
fragment ImageDetails on Image {
id
url
alt
__typename
}
fragment MediaDetails on Media {
id
type
url
duration
__typename
}
fragment SponsorDetails on Sponsor {
id
name
description
type
externalId
image16x9 {
...ImageDetails
__typename
}
thumbnail16x9 {
...ImageDetails
__typename
}
__typename
}
fragment NextEpisodeDetails on NextEpisode {
id
episodeNumber
seasonNumber
numberOfEpisodesInSeason
image16x9 {
...ImageDetails
__typename
}
__typename
}
'''