Upd horsy to 140320221219
This commit is contained in:
183
horsydist/resources/pafy_fix/backend_youtube_dl.py
Normal file
183
horsydist/resources/pafy_fix/backend_youtube_dl.py
Normal file
@@ -0,0 +1,183 @@
|
||||
import sys
|
||||
import time
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
if sys.version_info[:2] >= (3, 0):
|
||||
# pylint: disable=E0611,F0401,I0011
|
||||
uni = str
|
||||
else:
|
||||
uni = unicode
|
||||
|
||||
import youtube_dl
|
||||
|
||||
from .backend_shared import BasePafy, BaseStream, remux, get_status_string, get_size_done
|
||||
|
||||
dbg = logging.debug
|
||||
|
||||
|
||||
early_py_version = sys.version_info[:2] < (2, 7)
|
||||
|
||||
|
||||
class YtdlPafy(BasePafy):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._ydl_info = None
|
||||
self._ydl_opts = {'quiet': True, 'prefer_insecure': False, 'no_warnings': True}
|
||||
ydl_opts = kwargs.get("ydl_opts")
|
||||
if ydl_opts:
|
||||
self._ydl_opts.update(ydl_opts)
|
||||
super(YtdlPafy, self).__init__(*args, **kwargs)
|
||||
|
||||
def _fetch_basic(self):
|
||||
""" Fetch basic data and streams. """
|
||||
if self._have_basic:
|
||||
return
|
||||
|
||||
with youtube_dl.YoutubeDL(self._ydl_opts) as ydl:
|
||||
try:
|
||||
self._ydl_info = ydl.extract_info(self.videoid, download=False)
|
||||
# Turn into an IOError since that is what pafy previously raised
|
||||
except youtube_dl.utils.DownloadError as e:
|
||||
raise IOError(str(e).replace('YouTube said', 'Youtube says'))
|
||||
|
||||
if self.callback:
|
||||
self.callback("Fetched video info")
|
||||
|
||||
self._title = self._ydl_info['title']
|
||||
self._author = self._ydl_info['uploader']
|
||||
self._rating = self._ydl_info['average_rating']
|
||||
self._length = self._ydl_info['duration']
|
||||
self._viewcount = self._ydl_info['view_count']
|
||||
self._username = self._ydl_info['uploader_id']
|
||||
self._category = self._ydl_info['categories'][0] if self._ydl_info['categories'] else ''
|
||||
self._bestthumb = self._ydl_info['thumbnails'][0]['url']
|
||||
self._bigthumb = "http://i.ytimg.com/vi/%s/mqdefault.jpg" % self.videoid
|
||||
self._bigthumbhd = "http://i.ytimg.com/vi/%s/hqdefault.jpg" % self.videoid
|
||||
self.expiry = time.time() + 60 * 60 * 5
|
||||
|
||||
self._have_basic = True
|
||||
|
||||
def _fetch_gdata(self):
|
||||
""" Extract gdata values, fetch gdata if necessary. """
|
||||
if self._have_gdata:
|
||||
return
|
||||
|
||||
item = self._get_video_gdata(self.videoid)['items'][0]
|
||||
snippet = item['snippet']
|
||||
self._published = uni(snippet['publishedAt'])
|
||||
self._description = uni(snippet["description"])
|
||||
# Note: using snippet.get since some videos have no tags object
|
||||
self._keywords = [uni(i) for i in snippet.get('tags', ())]
|
||||
self._have_gdata = True
|
||||
|
||||
def _process_streams(self):
|
||||
""" Create Stream object lists from internal stream maps. """
|
||||
|
||||
if not self._have_basic:
|
||||
self._fetch_basic()
|
||||
|
||||
allstreams = [YtdlStream(z, self) for z in self._ydl_info['formats']]
|
||||
self._streams = [i for i in allstreams if i.mediatype == 'normal']
|
||||
self._audiostreams = [i for i in allstreams if i.mediatype == 'audio']
|
||||
self._videostreams = [i for i in allstreams if i.mediatype == 'video']
|
||||
self._m4astreams = [i for i in allstreams if i.extension == 'm4a']
|
||||
self._oggstreams = [i for i in allstreams if i.extension == 'ogg']
|
||||
self._allstreams = allstreams
|
||||
|
||||
|
||||
class YtdlStream(BaseStream):
|
||||
def __init__(self, info, parent):
|
||||
super(YtdlStream, self).__init__(parent)
|
||||
self._itag = info['format_id']
|
||||
|
||||
if (info.get('acodec') != 'none' and
|
||||
info.get('vcodec') == 'none'):
|
||||
self._mediatype = 'audio'
|
||||
elif (info.get('acodec') == 'none' and
|
||||
info.get('vcodec') != 'none'):
|
||||
self._mediatype = 'video'
|
||||
else:
|
||||
self._mediatype = 'normal'
|
||||
|
||||
self._threed = info.get('format_note') == '3D'
|
||||
self._rawbitrate = info.get('abr', 0) * 1024
|
||||
|
||||
height = info.get('height') or 0
|
||||
width = info.get('width') or 0
|
||||
self._resolution = str(width) + 'x' + str(height)
|
||||
self._dimensions = width, height
|
||||
self._bitrate = str(info.get('abr', 0)) + 'k'
|
||||
self._quality = self._bitrate if self._mediatype == 'audio' else self._resolution
|
||||
|
||||
self._extension = info['ext']
|
||||
self._notes = info.get('format_note') or ''
|
||||
self._url = info.get('url')
|
||||
|
||||
self._info = info
|
||||
|
||||
def get_filesize(self):
|
||||
""" Return filesize of the stream in bytes. Set member variable. """
|
||||
|
||||
# Faster method
|
||||
if 'filesize' in self._info and self._info['filesize'] is not None:
|
||||
return self._info['filesize']
|
||||
|
||||
# Fallback
|
||||
return super(YtdlStream, self).get_filesize()
|
||||
|
||||
def download(self, filepath="", quiet=False, progress="Bytes",
|
||||
callback=None, meta=False, remux_audio=False):
|
||||
|
||||
downloader = youtube_dl.downloader.http.HttpFD(ydl(),
|
||||
{'http_chunk_size': 10485760})
|
||||
|
||||
progress_available = ["KB", "MB", "GB"]
|
||||
if progress not in progress_available:
|
||||
progress = "Bytes"
|
||||
|
||||
status_string = get_status_string(progress)
|
||||
|
||||
def progress_hook(s):
|
||||
if s['status'] == 'downloading':
|
||||
bytesdone = s['downloaded_bytes']
|
||||
total = s['total_bytes']
|
||||
if s.get('speed') is not None:
|
||||
rate = s['speed'] / 1024
|
||||
else:
|
||||
rate = 0
|
||||
if s.get('eta') is None:
|
||||
eta = 0
|
||||
else:
|
||||
eta = s['eta']
|
||||
|
||||
progress_stats = (get_size_done(bytesdone, progress),
|
||||
bytesdone*1.0/total, rate, eta)
|
||||
if not quiet:
|
||||
status = status_string.format(*progress_stats)
|
||||
sys.stdout.write("\r" + status + ' ' * 4 + "\r")
|
||||
sys.stdout.flush()
|
||||
|
||||
if callback:
|
||||
callback(total, *progress_stats)
|
||||
|
||||
downloader._progress_hooks = [progress_hook]
|
||||
|
||||
if filepath and os.path.isdir(filepath):
|
||||
filename = self.generate_filename(max_length=256 - len('.temp'))
|
||||
filepath = os.path.join(filepath, filename)
|
||||
|
||||
elif filepath:
|
||||
pass
|
||||
|
||||
else:
|
||||
filepath = self.generate_filename(meta=meta, max_length=256 - len('.temp'))
|
||||
|
||||
infodict = {'url': self.url}
|
||||
|
||||
downloader.download(filepath, infodict)
|
||||
print()
|
||||
|
||||
if remux_audio and self.mediatype == "audio":
|
||||
subprocess.run(['mv', filepath, filepath + '.temp'])
|
||||
remux(filepath + '.temp', filepath, quiet=quiet, muxer=remux_audio)
|
||||
Reference in New Issue
Block a user