提问人:Benjamin 提问时间:11/10/2023 最后编辑:Benjamin 更新时间:11/11/2023 访问量:35
Python - yt_dlp 的进度从 100% 回到钩子响应中的“下沉”
Python - Progress of yt_dlp goes from 100% back to "downloding" in hook response
问:
我改编了我在这里找到的代码,它展示了如何在yt_dlp库中使用 python 钩子。我稍微打印出代码,只打印出状态和进度。
日志中有两件事我觉得很奇怪:
- 在达到 100% 之前,下载率从 91% 上升到 93%,然后又回到 90%。
- 完成后,控制台会打印出几行附加行,下载返回到“正在下载”。
知道这是怎么回事吗?
日志结束:
Status: downloading | Downloaded 91% 62552097/68667474 bytes
Status: downloading | Downloaded 93% 63600673/68667474 bytes
Status: downloading | Downloaded 90% 61765665/68667474 bytes
Status: downloading | Downloaded 90% 61634593/68667474 bytes
Status: downloading | Downloaded 96% 65697825/68667474 bytes
Status: downloading | Downloaded 90% 61569057/68667474 bytes
Status: downloading | Downloaded 90% 61536289/68667474 bytes
Status: finished | Downloaded 100% already
Status: downloading | Downloaded 100% 68667474/68667474 bytes
Status: downloading | Downloaded 90% 61519905/68667474 bytes
Status: downloading | Downloaded 90% 61511713/68667474 bytes
Status: downloading | Downloaded 90% 61507617/68667474 bytes
Status: downloading | Downloaded 90% 61505569/68667474 bytes
Status: downloading | Downloaded 75% 51466830/68667474 bytes
Status: downloading | Downloaded 75% 51465806/68667474 bytes
Status: downloading | Downloaded 60% 41180262/68667474 bytes
法典:
import asyncio
from functools import partial
import threading
from yt_dlp import YoutubeDL
from queue import LifoQueue, Empty
import sys
def main():
# Set the url to download
url = "xxxxx"
# Get the current event loop
loop = asyncio.get_event_loop()
# Create a Last In First Out Queue to communicate between the threads
queue = LifoQueue()
# Create the future which will be marked as done once the file is downloaded
coros = [youtube_dl(url, queue)]
future = asyncio.gather(*coros)
# Start a new thread to run the loop_in_thread function (with the positional arguments passed to it)
t = threading.Thread(target=loop_in_thread, args=[loop, future])
t.start()
# While the future isn't finished yet continue
while not future.done():
try:
# Get the latest status update from the que and print it
data = queue.get_nowait()
if data['status'] == 'downloading':
print('Status: ' + data['status'] + ' | Downloaded ' + "{:.0%}".format(data['downloaded_bytes']/data['total_bytes']) + ' ' + str(data['downloaded_bytes']) + '/' + str(data['total_bytes']) + ' bytes')
elif data['status'] == 'finished':
print('Status: ' + data['status'] + ' | Downloaded 100% already')
except Empty as e:
print('Status: Loading')
finally:
# Sleep between checking for updates
asyncio.run(asyncio.sleep(0.1))
def loop_in_thread(loop, future):
loop.run_until_complete(future)
async def youtube_dl(url, queue):
"""
Download
"""
yt_dlp_hook_partial = partial(yt_dlp_hook, queue)
ydl_opts = {
'quiet': True,
'noprogress': True,
'format': 'm4a/bestaudio/best',
'postprocessors': [{ # Extract audio using ffmpeg
'key': 'FFmpegExtractAudio',
'preferredcodec': 'm4a',
}],
'outtmpl': 'tmp_output/%(title)s [%(id)s].%(ext)s',
'progress_hooks': [yt_dlp_hook_partial]
}
with YoutubeDL(ydl_opts) as ydl:
return ydl.download([url])
def yt_dlp_hook(queue: LifoQueue, download):
"""
download Hook
Args:
download (_type_): _description_
"""
# Instead of logging the data just add the latest data to the queue
queue.put(download)
if __name__ == "__main__":
main()
答: 暂无答案
评论