Пример #1
0
 async def add_to_queue(self, query_string: str) -> Song:
     song = Song()
     # Check if query string is YT link
     if query_string.startswith('https://www.youtube.com/'):
         song.page_url = query_string
     # Or search with youtube_dlc otherwise
     else:
         options = {
             'format': 'bestaudio/best',
             'default_search': 'auto',
             'noplaylist': True
         }
         with youtube_dlc.YoutubeDL(options) as ydl:
             yt_entry = ydl.extract_info(query_string, download=False)
             video_id = yt_entry['entries'][0]['id']
             song.page_url = 'https://www.youtube.com/watch?v={}'.format(
                 video_id)
     downloader = youtube_dlc.YoutubeDL({
         'format': 'bestaudio',
         'title': True
     })
     yt_entry = downloader.extract_info(song.page_url, download=False)
     song.file_url = yt_entry.get('url')
     song.uploader = yt_entry.get('uploader')
     song.title = yt_entry.get('title')
     song.duration = yt_entry.get('duration')
     song.page_url = yt_entry.get('webpage_url')
     self.queue.append(song)
     if self.current_song is None:
         self.try_play_next_song()
     return song
Пример #2
0
    async def process_playlist(self, playlist_type, url):

        if playlist_type == linkutils.Playlist_Types.YouTube_Playlist:

            if ("playlist?list=" in url):
                listid = url.split('=')[1]
            else:
                video = url.split('&')[0]
                await self.process_song(video)
                return

            options = {
                'format': 'bestaudio/best',
                'extract_flat': True,
                "cookiefile": config.COOKIE_PATH
            }

            with youtube_dlc.YoutubeDL(options) as ydl:
                r = ydl.extract_info(url, download=False)

                for entry in r['entries']:

                    link = "https://www.youtube.com/watch?v={}".format(
                        entry['id'])

                    song = Song(linkutils.Origins.Playlist,
                                linkutils.Sites.YouTube,
                                webpage_url=link)

                    self.playlist.add(song)

        if playlist_type == linkutils.Playlist_Types.Spotify_Playlist:
            links = linkutils.get_spotify_playlist(url)
            for link in links:
                song = Song(linkutils.Origins.Playlist,
                            linkutils.Sites.Spotify,
                            webpage_url=link)
                self.playlist.add(song)

        if playlist_type == linkutils.Playlist_Types.BandCamp_Playlist:
            options = {'format': 'bestaudio/best', 'extract_flat': True}
            with youtube_dlc.YoutubeDL(options) as ydl:
                r = ydl.extract_info(url, download=False)

                for entry in r['entries']:

                    link = entry.get('url')

                    song = Song(linkutils.Origins.Playlist,
                                linkutils.Sites.Bandcamp,
                                webpage_url=link)

                    self.playlist.add(song)
Пример #3
0
def update_db():

	ydl = youtube_dlc.YoutubeDL({"ignoreerrors": True})


	with sql.connect(db_name) as conn:
		for query in queries:

			r = ydl.extract_info("ytsearchdate20:{}".format(query), download=False)
			video_list = r['entries']
			for video in video_list:
				if video is None:
					continue

				p = compute_prediction(video)

				# pegando a tag com o link do video
				video_id = video['webpage_url']
				watch_title = video['title'].replace("'", "")
				data_front = {"title": watch_title, "score": float(p), "video_id": video_id}
				data_front['update_time'] = time.time_ns()

				print(video_id, json.dumps(data_front))
				c = conn.cursor()
				c.execute("INSERT INTO videos VALUES ('{title}', '{video_id}', {score}, {update_time})".format(**data_front))
				conn.commit()
	return True
def get_video_title(download_url):
    try:
        with youtube_dlc.YoutubeDL(config.ydl_options) as ydl:
            return ydl.extract_info(download_url, download=False)['title']

    except Exception as e:
        print('error', e)
Пример #5
0
def fetch_metadata(url):
    stdout = io.StringIO()
    stderr = io.StringIO()
    info = None
    with youtube_dlc.YoutubeDL({'extract_flat': 'in_playlist'}) as ydl:
        ydl.params['extract_flat'] = 'in_playlist'
        return ydl.extract_info(url, download=False)
Пример #6
0
def download_video(download_opts, urlnum, urllist):
    with youtube_dlc.YoutubeDL(download_opts) as ydl:
        i = 0
        for url in urllist:
            while True:
                try:
                    ydl.extract_info(url, download=True)
                    wait_time(5, 20)
                except KeyboardInterrupt:
                    print("\nKeyboardInterrupt")
                    exit(1)
                except youtube_dlc.utils.YoutubeDLError:
                    youtube_dlc.utils.std_headers[
                        'User-Agent'] = youtube_dlc.utils.random_user_agent()
                    wait_time(1, 10)
                except:
                    print("\nother error")
                    exit(1)
                else:
                    youtube_dlc.utils.std_headers[
                        'User-Agent'] = youtube_dlc.utils.random_user_agent()
                    i += 1
                    print(
                        "\n\nDownloaded Items " + str(i) + "/" + str(urlnum) +
                        "\n\n"
                        "--------------------------------------------------------------"
                    )
                    break
Пример #7
0
 def download(self):
     try:
         with youtube_dl.YoutubeDL(self.options) as ydl:
             ydl.download([self.url])
     except:
         log.warning("Playlist at {} could not be downloaded.".format(
             id(self)))
Пример #8
0
async def get(session: CommandSession):
    args = session.current_arg_text.strip().split()

    if len(args) == 1:
        try:
            with youtube_dlc.YoutubeDL() as yt_dlc:
                info_dict = yt_dlc.extract_info(args[0], download=False)
                if is_duplicated(info_dict):
                    session.send('视频:“' + info_dict["title"] + '”已在队列中,请勿重复下载')
                    return
            info_dict['status'] = '等待中'
            info_dict['now_time'] = datetime.datetime.now().strftime(
                '%Y-%m-%d_%H:%M:%S.%f')
            download_list[info_dict['now_time']] = info_dict
            download_thread = threading.Thread(target=download_video,
                                               args=(session,
                                                     info_dict['now_time']))
            download_thread.start()
            session.send('视频:“' + info_dict["title"] + '”加入下载队列')
        except youtube_dlc.utils.UnsupportedError:
            exception_handler(f'解析失败:视频地址不受支持,请确认地址是否正确后再试。', logging.WARNING,
                              False, session.event.group_id)
        except youtube_dlc.utils.DownloadError as dl_error:
            exception_handler(f'解析失败:{dl_error.exc_info}', logging.ERROR)
        except Exception as e:
            exception_handler(f'解析失败:未知错误,请查看运行日志。', logging.ERROR, False,
                              session.event.group_id)
        return
    else:
        session.send("参数个数错误,仅支持一个参数,请检查后再试。")
Пример #9
0
    def download(self):
        if self.downloaded:
            return self.file_path

        out_template = str(self.file_path).replace(".mp3", ".%(ext)s")
        params = {
            "format":
            "bestaudio/best",
            "outtmpl":
            out_template,
            "noplaylist":
            True,
            "writethumbnail":
            True,
            "updatetime":
            False,
            "postprocessors": [
                {
                    "key": "FFmpegExtractAudio",
                    "preferredcodec": "mp3",
                    "preferredquality": "192",
                },
                {
                    "key": "FFmpegMetadata"
                },
            ],
        }
        with youtube_dlc.YoutubeDL(params) as ydl:
            ydl.extract_info(self.url)

        return self.file_path
Пример #10
0
    async def play_song(self, song):
        """Plays a song object"""

        if song.origin == linkutils.Origins.Playlist:
            if song.host == linkutils.Sites.Spotify:
                conversion = await self.search_youtube(
                    linkutils.convert_spotify(song.info.webpage_url))
                song.info.webpage_url = conversion

            downloader = youtube_dlc.YoutubeDL({
                'format': 'bestaudio',
                'title': True,
                "cookiefile": config.COOKIE_PATH
            })
            r = downloader.extract_info(song.info.webpage_url, download=False)

            song.base_url = r.get('url')
            song.info.uploader = r.get('uploader')
            song.info.title = r.get('title')
            song.info.duration = r.get('duration')
            song.info.webpage_url = r.get('webpage_url')
            song.info.thumbnail = r.get('thumbnails')[0]['url']

        self.playlist.add_name(song.info.title)
        self.current_song = song

        self.voice_client.play(discord.FFmpegPCMAudio(
            song.base_url,
            before_options=
            '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5'),
                               after=lambda e: self.next_song(e))

        self.voice_client.source = discord.PCMVolumeTransformer(
            self.guild.voice_client.source)
        self.voice_client.source.volume = float(self.volume) / 100.0
def write_from_link(download_url):
    try:
        with youtube_dlc.YoutubeDL(config.ydl_options) as ydl:
            meta = ydl.extract_info(download_url, download=True)
            return meta['id'], meta['title'], meta['duration']
    except Exception as e:
        print('error', e)
def addSong(url, artistOverride, albumOverride, copyToItunes):

    # download mp3
    with youtube_dlc.YoutubeDL(ydl_opts) as ydl:
        try:
            info = ydl.extract_info(url)
        except Exception as e:
            return [1, e]
        videoTitle = info['title']
        songName = info['track'] or 'NA'
        meta = MP4("song/" + songName + '.m4a')
        meta['\xa9cmt'] = ''
        meta['\xa9day'] = meta['\xa9day'][0][0:4]
        if songName == 'NA':
            meta['\xa9ART'] = ''
        if artistOverride != '':
            meta['\xa9ART'] = artistOverride
        if albumOverride != '':
            meta['\xa9alb'] = albumOverride
        meta.save()
        fileName = songName + '.m4a'
        if songName == 'NA':
            os.rename("song/" + fileName,
                      localMusicFolder + videoTitle + ".m4a")
            fileName = videoTitle + ".m4a"
        else:
            os.rename("song/" + fileName, localMusicFolder + fileName)
        if copyToItunes:
            copyfile(localMusicFolder + fileName,
                     itunesAutoImportFolder + fileName)

    print("Completed successfully")
    return [0, fileName]
Пример #13
0
def download_video(session, time):
    bot = nonebot.get_bot()
    video_info = download_list[time]
    logging.info("Start Downloading...")

    class Logger(object):
        @staticmethod
        def debug(msg):
            if 'Deleting' in msg:
                if '.flv' in msg or '.m4a' in msg:
                    if video_info['status'] != '上传中':
                        video_info['status'] = '上传中'
                    # send_message_auto(session, '成功转码视频:“' + video_info['title'] + '”,开始上传到OneDrive')
                    upload_video(session, video_info)
                    if download_list:
                        download_list.pop(time)
                    else:
                        print("[WARN]Download List not exist.")

        @staticmethod
        def warning(msg):
            exception_handler(f'YoutubeDLC:{msg}', logging.WARNING)

        @staticmethod
        def error(msg):
            exception_handler(f'YoutubeDLC:{msg}', logging.ERROR)

    def tracker(data):
        nonlocal video_info
        if data['status'] == 'downloading':
            video_info['status'] = '已下载' + data['_percent_str']
        if data['status'] == 'finished' and ('.flv' in data['filename']
                                             or '.m4a' in data['filename']):
            if video_info['status'] != '转码中':
                video_info['status'] = '转码中'
            # send_message_auto(session, '成功下载视频:“' + video_info['title'] + '”,开始转码')

    options = {
        'format':
        'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
        'progress_hooks': [tracker],
        'logger':
        Logger(),
        'merge_output_format':
        'mp4',
        'postprocessors': [{
            'key': 'FFmpegVideoConvertor',
            'preferedformat': 'mp4'
        }],
        'outtmpl':
        f'{CACHE_PATH}{time}.%(ext)s',
    }
    try:
        with youtube_dlc.YoutubeDL(options) as yt_dlc:
            yt_dlc.download([video_info['webpage_url']])
    except Exception:
        exception_handler(f'下载失败:下载过程中出现错误,请排除队列错误后再试。', logging.ERROR, False,
                          session.event.group_id)
Пример #14
0
	def getData(self, base_url, tag, query_filter, max_pages, pagesize, num_videos):
		'''
		returns a dataframe with information from youtube and satckoverflow or stackexchenge that was scrapped.
		
		Paramaters
		----------
		base_url: url path to all question filter by a tag >> parameter to stackScrape class
					- stackexchange: https://stats.stackexchange.com/questions/tagged/
					- stackoverflow: https://stackoverflow.com/questions/tagged/

		tag: tag to be filtered (e.g.: 'python', 'r', 'javascript', ...) >> parameter to stackScrape class

		query_filter: filter to perform a query ('Newest', 'Active', 'Bounties', 'Unanswered', 'Frequent', Votes') >> parameter to stackScrape class

		max_pages: the maximum number of pages to be scraped >> parameter to stackScrape class

		pagesize: the number of records per page (the maximum number is 50) >> parameter to stackScrape class
		
		num_videos: Number of videos in each query for youtube scrapping
		
		Return
		------
		A DataFrame
		'''		
		# YoutubeDL class initialization
		ydl = youtube_dlc.YoutubeDL({'ignoreerrors':True})
		
		# Getting Stack data
		dfStack = self.stack.TagsStack(base_url, tag, query_filter, max_pages, pagesize)
		
		# Rename columns of Stack DataFrame
		dfStack = YoutubeData.renameStackColumns(self, dfStack)
		
		# Array of tags for the youtube query
		arrayQuery = dfStack['TagStack'].to_list()

		results = list()
		# loop in each tag of the array of tags
		for query in arrayQuery:
			# Append string python for getting video with python relation 
			queryConcat = query + ' python'
			# Extract info from Youtube
			r = ydl.extract_info('ytsearchdate{}:\{}'.format(num_videos, queryConcat), download=False)
			# loop in each result of the extraction 
			for entry in r['entries']:
				# Add the Query Column into Dataframe
				if entry is not None:
					entry['Query'] = query
			# Append all the videos of each tag into a list		
			results += r['entries']
		# Exclude None	
		results = [e for e in results if e is not None]
		# DataFrame
		dfYoutube = pd.DataFrame(results)
		# Merge Stack and Youtube Dataframe
		dfResult = YoutubeData.mergeYotubeStackData(self, dfYoutube, dfStack)
		return dfResult
Пример #15
0
 def get_info_dict(self) -> None:
     with youtube_dl.YoutubeDL(self.options) as ydl:
         try:
             self.info_dict = ydl.extract_info(self.url, download=False)
             log.debug(f"Populated metadata for {self.url} successfully.")
             # TODO make the error handling here better
         except:
             log.error(f"Populating metadata for {self.url} failed")
             self.error = True
Пример #16
0
def write_from_link(download_url):
    try:
        with youtube_dlc.YoutubeDL(config.ydl_options) as ydl:
            meta = ydl.extract_info(download_url, download=True)
            if meta['formats'][0]['filesize'] > config.max_file_size:
                raise Exception("File too large")
            return meta['id'], meta['title'], meta['duration']
    except Exception as e:
        print('error', e)
Пример #17
0
def download_video(download_opts, urlnum, urllist, out_path, ext_str):
    file_list = []
    with youtube_dlc.YoutubeDL(download_opts) as ydl:
        downloaded_count = 0
        skiped_count = 0
        count = 1
        max_retry_count = 3
        for url in urllist:
            while True:
                try:
                    info_dict = ydl.extract_info(url, download=True)
                    o = json.loads(json.dumps(info_dict, ensure_ascii=False))
                    title_byte = o['title'].encode('cp932', 'ignore')
                    title_str = title_byte.decode('cp932')
                    uploader_byte = o['uploader'].encode('cp932', 'ignore')
                    uploader_str = uploader_byte.decode('cp932')
                    file_path = out_path + '/' + uploader_str + '/' + title_str + ext_str
                    file_list.append(file_path)
                    wait_time(3, 6)
                except KeyboardInterrupt:
                    logger.info("\nKeyboardInterrupt")
                    return file_list
                    # exit(1)
                except youtube_dlc.utils.YoutubeDLError as you_err:
                    logger.error(you_err)
                    logger.error('url:' + url)
                    count += 1
                    if count >= max_retry_count:
                        skiped_count += 1
                        logger.debug("Skipped Items " + str(skiped_count) + "/" + str(urlnum))
                        break
                    youtube_dlc.utils.std_headers['User-Agent']=youtube_dlc.utils.random_user_agent()
                    wait_time(1, 6)
                except Exception as err:
                    logger.error(err)
                    logger.error('url:' + url)
                    skiped_count += 1
                    logger.debug("Skipped Items " + str(skiped_count) + "/" + str(urlnum))
                    break
                except:
                    logger.error("Other error")
                    logger.error('url:' + url)
                    skiped_count += 1
                    logger.debug("Skipped Items " + str(skiped_count) + "/" + str(urlnum))
                    break
                    # exit(1)
                else:
                    youtube_dlc.utils.std_headers['User-Agent']=youtube_dlc.utils.random_user_agent()
                    downloaded_count += 1
                    # UnicodeDecodeErrorの回避
                    logger.debug("Downloaded: " + title_str)
                    logger.debug("Downloaded Items " + str(downloaded_count) + "/" + str(urlnum))
                    break

        return file_list
Пример #18
0
def youtube_dl_func(url, ydl_opts, queue=None):
    ydl = youtube_dl.YoutubeDL(ydl_opts)
    try:
        ydl.download([url])
    except Exception as exc:
        ydl_status = 1, str(exc)
        # ydl_status = exc  #TODO: pass and re-raise original Exception
    else:
        ydl_status = 0, "OK"
    if queue:
        queue.put(ydl_status)
    else:
        return ydl_status
Пример #19
0
def flat_playlist(flat_list):
    with youtube_dlc.YoutubeDL(flat_list) as ydl:
        try:
            info_dict = ydl.extract_info(playlist, download=False)
        except youtube_dlc.utils.YoutubeDLError:
            print("\nNot get playlist. Check playlist-id and retry")
            exit(1)
        except:
            print("\nother error")
            exit(1)
        o = json.loads(json.dumps(info_dict, ensure_ascii=False))
    urllist = []
    for items in o["entries"]:
        urllist.append("https://www.youtube.com/watch?v=" + items["id"])
    urlnum = len(urllist)
    return urlnum, urllist
Пример #20
0
def flat_channel(flat_list, channel_url):
    with youtube_dlc.YoutubeDL(flat_list) as ydl:
        try:
            info_dict = ydl.extract_info(channel_url, download=False)
        except youtube_dlc.utils.YoutubeDLError as youtube_err:
            logger.info("\nNot get playlist. Check playlist-id and retry")
            raise youtube_err
            # exit(1)
        except:
            logger.error("\nother error")
            raise Exception
            # exit(1)
        o = json.loads(json.dumps(info_dict, ensure_ascii=False))
    url = ""
    url = o["url"]
    return url
Пример #21
0
def download_video(vidlink, start_sec, end_sec):
    ydl = youtube_dlc.YoutubeDL({'format': 'best/best'}, )

    with ydl:
        video = ydl.extract_info(vidlink, download=False)
    url = video['url']
    fps = video['fps']

    start_time = sec_to_time(start_sec)
    duration_time = sec_to_time(end_sec - start_sec)

    if os.path.exists('vid.mp4'):
        os.remove('vid.mp4')

    os.system("ffmpeg -i '%s' -ss %s -t %s -async 1 -strict -2 'vid.mp4'" %
              (url, start_time, duration_time))
Пример #22
0
def predict_api(id_video):

    ydl = youtube_dlc.YoutubeDL({"ignoreerrors": True})
    video_json_data = ydl.extract_info(
        "https://www.youtube.com/watch?v={}".format(id_video), download=False)

    if video_json_data is None:
        return "not found"

    p = ml_utils.compute_prediction(video_json_data)
    output = {
        "title": video_json_data['title'],
        "score": p,
        "link": "https://www.youtube.com/watch?v={}".format(id_video)
    }

    return output
Пример #23
0
def download(url, request_options, output, job_id):
    with youtube_dlc.YoutubeDL(get_ydl_options(request_options)) as ydl:
        ydl.params['extract_flat'] = 'in_playlist'
        ydl_opts = ChainMap(os.environ, app_defaults)
        info = ydl.extract_info(url, download=False)
        if 'title' in info and info['title']:
            jobshandler.put((Actions.SET_NAME, (job_id, info['title'])))
        if '_type' in info and info['_type'] == 'playlist' \
                and 'YDL_OUTPUT_TEMPLATE_PLAYLIST' in ydl_opts:
            ydl.params['outtmpl'] = ydl_opts['YDL_OUTPUT_TEMPLATE_PLAYLIST']
        ydl.params['extract_flat'] = False

        # Swap out sys.stdout as ydl's output so we can capture it
        ydl._screen_file = output
        ydl._err_file = ydl._screen_file
        ydl.download([url])
        return ydl._screen_file.getvalue()
Пример #24
0
    def downloadVideo(self):
        with open('links.txt', 'r') as file:
            links = file.readlines()

        if links == []:
            self.dw.show()
            self.LinksNotFound()

        else:
            ydl_opts = {'format': 'bestvideo/best',
                        'outtmpl': f"{self.directory}\%(title)s.%(ext)s",
                        'progress_hooks': [self.progressHook],
                        'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp4', 'preferredquality': '192',}]}

            for link in links:
                with youtube_dlc.YoutubeDL(ydl_opts) as ydl:
                    ydl.download([link])
Пример #25
0
def download(vid):
    '''Downloads the video specified by the video id'''
    #Search could not find anything
    if vid == None:
        return None

    #Downloads the video with the url
    url = YT_VIDEO_BASE.format(vid)
    data = {}
    try:
        with youtube_dlc.YoutubeDL(YDL_OPTIONS) as ydl:
            info = ydl.extract_info(url, download=False)
            download_target = ydl.prepare_filename(info)

            #Setup file name
            targ = download_target.split('.')
            targ[-1] = 'wav'
            targ = '.'.join(targ)
            config = Path(targ)

            #Only download if it doesn't already exist
            if not config.is_file():
                #If the folder is too full
                songs = Path("songs")
                files = glob.glob("songs/*")
                n = sum(os.stat(f).st_size for f in files)
                if n > MAX_ALLOCATION:
                    print("Currently deleting songs in cache")
                    files.sort(key=os.path.getmtime, reverse=True)
                    for i in range(len(files)//2):
                        os.remove(files[i])
    
                ydl.download([url])

            data['target'] = targ
            data['url'] = url
            data['title'] = html.unescape(info['title'])
            data['thumbnail'] = info['thumbnails'][0]['url']
            data['downloaded'] = True

            #DIAGNOSTIC print statements (WOOHOO)
            print(f'Downloading: {info["title"]}')
            return data
    except:
        return None
Пример #26
0
    async def search_youtube(self, title):
        """Searches youtube for the video title and returns the first results video link"""

        # if title is already a link
        if linkutils.get_url(title) is not None:
            return title

        options = {
            'format': 'bestaudio/best',
            'default_search': 'auto',
            'noplaylist': True,
            "cookiefile": config.COOKIE_PATH
        }

        with youtube_dlc.YoutubeDL(options) as ydl:
            r = ydl.extract_info(title, download=False)

        videocode = r['entries'][0]['id']

        return "https://www.youtube.com/watch?v={}".format(videocode)
Пример #27
0
    def video_from_url(self, bot: Bot, update: Update):
        """Download video from URL

        Args:
            bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object.
            update (:obj:`telegram.update.Update`): Telegram Api Update Object
        """
        user_id = update.message.from_user.id

        if self.video_information.get(user_id, None):
            self.abort(bot, update)

        chat_id = update.message.chat_id
        url = urldefrag(update.message.text).url
        # Remove potential playlist argument from url
        url = re.sub('([&?])list=.*(&|$)', '\g<1>', url)

        with youtube_dlc.YoutubeDL({}) as ydl:
            try:
                info = ydl.extract_info(url, download=False)
            except DownloadError:
                return
            info['short_description'] = re.sub(r'\n\s*\n', '\n', (info.get('description', '') or ''))
            self.video_information[user_id] = info
            keyboard = self.get_keyboard('format', info)

            self.current_menu[user_id] = 'format'
            self.keyboard_message_id[user_id] = bot.send_message(
                chat_id=chat_id,
                text='<a href="{webpage_url}">&#8205;</a>'
                     '{extractor_key:-^20}\n'
                     '<b>{uploader} - {title}</b>\n'
                     '{short_description:.150}...'.format(**info),
                parse_mode=ParseMode.HTML,
                disable_web_page_preview=False,
                reply_markup=keyboard
            ).result()
Пример #28
0
 def download(self):
     with youtube_dl.YoutubeDL(self.options) as ydl:
         ydl.download([self.url])
Пример #29
0
    def download(self, bot: Bot, update: Update):
        """Download video from URL

        Args:
            bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object.
            update (:obj:`telegram.update.Update`): Telegram Api Update Object
        """
        user_id = update.effective_user.id
        chat_id = update.effective_chat.id
        url = self.video_information[user_id]['webpage_url']
        data = update.callback_query.data.split(' ')
        message = update.effective_message

        class DownloadHook:
            progress_bar = None
            can_send_status = True

            def hook(self, download_event: dict):
                """Hook for download

                Args:
                    download_event (:obj:`dict`): Dictionary with information about the event and the file
                """
                if download_event['status'] == 'downloading' and self.can_send_status:
                    total_amount = download_event.get('total_bytes', None)
                    downloaded = download_event['downloaded_bytes']
                    fragments = False

                    if not total_amount:
                        fragments = True
                        total_amount = download_event.get('fragment_count', None)
                        downloaded = download_event.get('fragment_index', None)

                    if total_amount is not None:
                        if self.progress_bar is None:
                            self.progress_bar = TelegramProgressBar(
                                bot=bot,
                                chat_id=chat_id,
                                full_amount=total_amount if fragments else total_amount / 1000000,
                                pre_message='Downloading Video\n{current} / {total} %s' % (
                                    'fragments' if fragments else 'MB')
                            )
                            self.progress_bar.start()
                            return
                        self.progress_bar.update(
                            new_amount=downloaded if fragments else downloaded / 1000000,
                            new_full_amount=total_amount if fragments else total_amount / 1000000
                        )
                    else:
                        self.can_send_status = False
                        bot.send_message(chat_id=chat_id, text='Downloading Video\nNo download status available.')

        format_id = data[2]
        if format_id == 'best':
            if data[1] == 'video':
                format_id = 'bestvideo/best'
            elif data[1] == 'audio':
                format_id = 'bestaudio'
            elif data[1] == 'video_audio':
                format_id = 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best'  # best mp4 wiht best m4a

        with TemporaryDirectory() as temp_dir:
            download_hook = DownloadHook()
            options = {
                'outtmpl': os.path.join(temp_dir, '%(uploader)s - %(title)s [%(id)s].%(ext)s'),
                'restrictfilenames': True,
                'progress_hooks': [download_hook.hook],
            }
            if format_id:
                options['format'] = format_id

            if data[1] == 'audio' and data[2] == 'best':
                options['postprocessors'] = [{
                    'key': 'FFmpegExtractAudio',
                    'preferredcodec': 'mp3',
                    'preferredquality': '192',
                }]

            # Remove buttons
            message.edit_text(text=message.text_html, parse_mode=ParseMode.HTML)
            with youtube_dlc.YoutubeDL(options) as ydl:
                ydl.download([url, ])

                filename = os.listdir(temp_dir)[0]
                file_path = os.path.join(temp_dir, filename)

                file_size = os.path.getsize(file_path)
                sent = False
                if file_size < 5e+7:
                    try:
                        bot.send_chat_action(chat_id=chat_id, action=ChatAction.UPLOAD_VIDEO)

                        bot.send_message(chat_id=chat_id, text='Depending on the filesize the upload could take some '
                                                               'time')
                        bot.send_document(chat_id=chat_id, document=open(file_path, mode='rb'), filename=filename,
                                          timeout=60)
                        sent = True
                    except (NetworkError, TimedOut, BadRequest):
                        pass

                if not sent:
                    bot.send_chat_action(chat_id=chat_id, action=ChatAction.UPLOAD_VIDEO)
                    uploader.connect()
                    uploader.upload(file_path, remove_after=1800)
                    uploader.close()

                    path = UPLOADER.get('url', None) or UPLOADER['configuration'].get('path', None) or ''
                    url_path = os.path.join(path, filename)

                    if os.path.isfile(url_path):
                        # Can not send a download link to the user if the file is stored locally without url config
                        bot.send_message(
                            chat_id=update.effective_chat.id,
                            text='The file was to big to sent or for some reason could not be sent directly. Another '
                                 'way of sending the file was not configured by the adminstrator. You can use /support '
                                 'to contact the admins.')
                        return

                    keyboard = InlineKeyboardMarkup([[InlineKeyboardButton('Download', url=url_path), ], ])
                    bot.send_message(
                        chat_id=update.effective_chat.id,
                        text='File was either too big for Telegram or could for some reason not be sent directly, '
                             'please use this download button',
                        reply_markup=keyboard)

                self.current_menu.pop(user_id, None)
                self.keyboard_message_id.pop(user_id, None)
                self.video_information.pop(user_id, None)
        if artistOverride != '':
            meta['\xa9ART'] = artistOverride
        if albumOverride != '':
            meta['\xa9alb'] = albumOverride
        meta.save()
        fileName = songName + '.m4a'
        if songName == 'NA':
            os.rename("song/" + fileName,
                      localMusicFolder + videoTitle + ".m4a")
            fileName = videoTitle + ".m4a"
        else:
            os.rename("song/" + fileName, localMusicFolder + fileName)
        if copyToItunes:
            copyfile(localMusicFolder + fileName,
                     itunesAutoImportFolder + fileName)

    print("Completed successfully")
    return [0, fileName]


if __name__ == "__main__":
    url = 'https://www.youtube.com/watch?v=wW80mkZaYxY'
    with youtube_dlc.YoutubeDL(ydl_opts) as ydl:
        pass
        ret = ydl.extract_info(url)
        name = ret['track'] + '.m4a'
        print(ret['title'])
        meta = MP4("song/" + name)
        meta['\xa9cmt'] = ''
        meta['\xa9day'] = meta['\xa9day'][0][0:4]
        meta.save()