]> jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/veoh.py
[exractor/lbry] Use HEAD request for redirect URL (#4181)
[yt-dlp.git] / yt_dlp / extractor / veoh.py
1 from .common import InfoExtractor
2 from ..utils import (
3 int_or_none,
4 parse_duration,
5 qualities,
6 try_get
7 )
8
9
10 class VeohIE(InfoExtractor):
11 _VALID_URL = r'https?://(?:www\.)?veoh\.com/(?:watch|videos|embed|iphone/#_Watch)/(?P<id>(?:v|e|yapi-)[\da-zA-Z]+)'
12
13 _TESTS = [{
14 'url': 'http://www.veoh.com/watch/v56314296nk7Zdmz3',
15 'md5': '620e68e6a3cff80086df3348426c9ca3',
16 'info_dict': {
17 'id': 'v56314296nk7Zdmz3',
18 'ext': 'mp4',
19 'title': 'Straight Backs Are Stronger',
20 'description': 'md5:203f976279939a6dc664d4001e13f5f4',
21 'thumbnail': 're:https://fcache\\.veoh\\.com/file/f/th56314296\\.jpg(\\?.*)?',
22 'uploader': 'LUMOback',
23 'duration': 46,
24 'view_count': int,
25 'average_rating': int,
26 'comment_count': int,
27 'age_limit': 0,
28 'categories': ['technology_and_gaming'],
29 'tags': ['posture', 'posture', 'sensor', 'back', 'pain', 'wearable', 'tech', 'lumo'],
30 },
31 }, {
32 'url': 'http://www.veoh.com/embed/v56314296nk7Zdmz3',
33 'only_matching': True,
34 }, {
35 'url': 'http://www.veoh.com/watch/v27701988pbTc4wzN?h1=Chile+workers+cover+up+to+avoid+skin+damage',
36 'md5': '4a6ff84b87d536a6a71e6aa6c0ad07fa',
37 'info_dict': {
38 'id': '27701988',
39 'ext': 'mp4',
40 'title': 'Chile workers cover up to avoid skin damage',
41 'description': 'md5:2bd151625a60a32822873efc246ba20d',
42 'uploader': 'afp-news',
43 'duration': 123,
44 },
45 'skip': 'This video has been deleted.',
46 }, {
47 'url': 'http://www.veoh.com/watch/v69525809F6Nc4frX',
48 'md5': '4fde7b9e33577bab2f2f8f260e30e979',
49 'note': 'Embedded ooyala video',
50 'info_dict': {
51 'id': '69525809',
52 'ext': 'mp4',
53 'title': 'Doctors Alter Plan For Preteen\'s Weight Loss Surgery',
54 'description': 'md5:f5a11c51f8fb51d2315bca0937526891',
55 'uploader': 'newsy-videos',
56 },
57 'skip': 'This video has been deleted.',
58 }, {
59 'url': 'http://www.veoh.com/watch/e152215AJxZktGS',
60 'only_matching': True,
61 }, {
62 'url': 'https://www.veoh.com/videos/v16374379WA437rMH',
63 'md5': 'cceb73f3909063d64f4b93d4defca1b3',
64 'info_dict': {
65 'id': 'v16374379WA437rMH',
66 'ext': 'mp4',
67 'title': 'Phantasmagoria 2, pt. 1-3',
68 'description': 'Phantasmagoria: a Puzzle of Flesh',
69 'thumbnail': 're:https://fcache\\.veoh\\.com/file/f/th16374379\\.jpg(\\?.*)?',
70 'uploader': 'davidspackage',
71 'duration': 968,
72 'view_count': int,
73 'average_rating': int,
74 'comment_count': int,
75 'age_limit': 18,
76 'categories': ['technology_and_gaming', 'gaming'],
77 'tags': ['puzzle', 'of', 'flesh'],
78 }
79 }]
80
81 def _real_extract(self, url):
82 video_id = self._match_id(url)
83 metadata = self._download_json(
84 'https://www.veoh.com/watch/getVideo/' + video_id,
85 video_id)
86 video = metadata['video']
87 title = video['title']
88
89 thumbnail_url = None
90 q = qualities(['Regular', 'HQ'])
91 formats = []
92 for f_id, f_url in video.get('src', {}).items():
93 if not f_url:
94 continue
95 if f_id == 'poster':
96 thumbnail_url = f_url
97 else:
98 formats.append({
99 'format_id': f_id,
100 'quality': q(f_id),
101 'url': f_url,
102 })
103 self._sort_formats(formats)
104
105 categories = metadata.get('categoryPath')
106 if not categories:
107 category = try_get(video, lambda x: x['category'].strip().removeprefix('category_'))
108 categories = [category] if category else None
109 tags = video.get('tags')
110
111 return {
112 'id': video_id,
113 'title': title,
114 'description': video.get('description'),
115 'thumbnail': thumbnail_url,
116 'uploader': video.get('author', {}).get('nickname'),
117 'duration': int_or_none(video.get('lengthBySec')) or parse_duration(video.get('length')),
118 'view_count': int_or_none(video.get('views')),
119 'formats': formats,
120 'average_rating': int_or_none(video.get('rating')),
121 'comment_count': int_or_none(video.get('numOfComments')),
122 'age_limit': 18 if video.get('contentRatingId') == 2 else 0,
123 'categories': categories,
124 'tags': tags.split(', ') if tags else None,
125 }