YouTube音频文件的内容直接到Azure BlobStorage

问题描述 投票:0回答:1

但是它扔了

TypeError: write() argument must be str, not <class 'bytes'>

我感谢任何帮助。
Edit:完整的追溯:

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[4], line 27 24 # Download video and upload to Azure Blob Storage 25 with YoutubeDL(ydl_opts) as ydl, io.BytesIO() as byte_stream: 26 # Redirect yt-dlp's stdout to the byte stream ---> 27 ydl.download([video_url]) 28 byte_stream.seek(0) 29 blob_client.upload_blob(byte_stream, overwrite=True) File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:3618, in YoutubeDL.download(self, url_list) 3615 raise SameFileError(outtmpl) 3617 for url in url_list: -> 3618 self.__download_wrapper(self.extract_info)( 3619 url, force_generic_extractor=self.params.get('force_generic_extractor', False)) 3621 return self._download_retcode File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:3591, in YoutubeDL.__download_wrapper.<locals>.wrapper(*args, **kwargs) 3588 @functools.wraps(func) 3589 def wrapper(*args, **kwargs): 3590 try: -> 3591 res = func(*args, **kwargs) 3592 except CookieLoadError: 3593 raise File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:1626, in YoutubeDL.extract_info(self, url, download, ie_key, extra_info, process, force_generic_extractor) 1624 raise ExistingVideoReached 1625 break -> 1626 return self.__extract_info(url, self.get_info_extractor(key), download, extra_info, process) 1627 else: 1628 extractors_restricted = self.params.get('allowed_extractors') not in (None, ['default']) File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:1637, in YoutubeDL._handle_extraction_exceptions.<locals>.wrapper(self, *args, **kwargs) 1635 while True: 1636 try: -> 1637 return func(self, *args, **kwargs) 1638 except (CookieLoadError, DownloadCancelled, LazyList.IndexError, PagedList.IndexError): 1639 raise File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:1793, in YoutubeDL.__extract_info(self, url, ie, download, extra_info, process) 1791 if process: 1792 self._wait_for_video(ie_result) -> 1793 return self.process_ie_result(ie_result, download, extra_info) 1794 else: 1795 return ie_result File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:1852, in YoutubeDL.process_ie_result(self, ie_result, download, extra_info) 1850 if result_type == 'video': 1851 self.add_extra_info(ie_result, extra_info) -> 1852 ie_result = self.process_video_result(ie_result, download=download) 1853 self._raise_pending_errors(ie_result) 1854 additional_urls = (ie_result or {}).get('additional_urls') File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:3024, in YoutubeDL.process_video_result(self, info_dict, download) 3022 downloaded_formats.append(new_info) 3023 try: -> 3024 self.process_info(new_info) 3025 except MaxDownloadsReached: 3026 max_downloads_reached = True File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:177, in _catch_unsafe_extension_error.<locals>.wrapper(self, *args, **kwargs) 174 @functools.wraps(func) 175 def wrapper(self, *args, **kwargs): 176 try: --> 177 return func(self, *args, **kwargs) 178 except _UnsafeExtensionError as error: 179 self.report_error( 180 f'The extracted extension ({error.extension!r}) is unusual ' 181 'and will be skipped for safety reasons. ' 182 f'If you believe this is an error{bug_reports_message(",")}') File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:3492, in YoutubeDL.process_info(self, info_dict) 3488 dl_filename = existing_video_file(full_filename, temp_filename) 3489 if dl_filename is None or dl_filename == temp_filename: 3490 # dl_filename == temp_filename could mean that the file was partially downloaded with --no-part. 3491 # So we should try to resume the download -> 3492 success, real_download = self.dl(temp_filename, info_dict) 3493 info_dict['__real_download'] = real_download 3494 else: File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/YoutubeDL.py:3212, in YoutubeDL.dl(self, name, info, subtitle, test) 3210 if new_info.get('http_headers') is None: 3211 new_info['http_headers'] = self._calc_headers(new_info) -> 3212 return fd.download(name, new_info, subtitle) File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/downloader/common.py:464, in FileDownloader.download(self, filename, info_dict, subtitle) 461 self.to_screen(f'[download] Sleeping {sleep_interval:.2f} seconds ...') 462 time.sleep(sleep_interval) --> 464 ret = self.real_download(filename, info_dict) 465 self._finish_multiline_status() 466 return ret, True File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/downloader/http.py:368, in HttpFD.real_download(self, filename, info_dict) 366 try: 367 establish_connection() --> 368 return download() 369 except RetryDownload as err: 370 retry.error = err.source_error File ~/.virtualenvs/myenv/lib/python3.12/site-packages/yt_dlp/downloader/http.py:279, in HttpFD.real_download.<locals>.download() 276 self.report_error(f'unable to set filesize xattr: {err}') 278 try: --> 279 ctx.stream.write(data_block) 280 except OSError as err: 281 self.to_stderr('\n') File ~/.virtualenvs/myenv/lib/python3.12/site-packages/ipykernel/iostream.py:668, in OutStream.write(self, string) 666 if not isinstance(string, str): 667 msg = f"write() argument must be str, not {type(string)}" # type:ignore[unreachable] --> 668 raise TypeError(msg) 670 if self.echo is not None: 671 try: TypeError: write() argument must be str, not <class 'bytes'>

	
您面临此错误,因为

yt-dlp

将视频数据写为

bytes

,但它是指向

stdout
,它默认情况下会引起
String
python python-3.x azure-blob-storage youtube-dl yt-dlp
1个回答
0
投票
io.BytesIO()

用作内存缓冲区并修改

outtmpl
postprocessors设置以直接编写字节。
import io
from yt_dlp import YoutubeDL
from azure.storage.blob import BlobServiceClient


video_url = 'https://www.youtube.com/watch?v=<video_id>'


connect_str = 'DefaultEndpointsProtocol=https;AccountName=accountname;AccountKey=accountkey;EndpointSuffix=core.windows.net'
container_name = 'container_name'
blob_name = 'video_name.mp4'

blob_service_client = BlobServiceClient.from_connection_string(connect_str)
blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)

class BytesIOWrapper(io.BytesIO):
    """ Custom wrapper to handle yt-dlp writing video data into memory """
    def write(self, b):
        super().write(b)
        return len(b)  # yt-dlp expects write() to return the number of bytes written

    # yt-dlp optionsto write video as bytes
ydl_opts = {
    'format': 'best',
    'quiet': True,
    'outtmpl': '-',
    'noprogress': True,
    'postprocessors': [{
        'key': 'FFmpegVideoConvertor',
        'preferedformat': 'mp4'        # ensure the output format is mp4
    }],
    'logger': None
}

    # stream video directly to azure blob storege
with YoutubeDL(ydl_opts) as ydl, BytesIOWrapper() as byte_stream:
    ydl.download([video_url])  # Download the video
    byte_stream.seek(0)  # Reset stream pointer to start
    blob_client.upload_blob(byte_stream, overwrite=True)  #uploading to azure

print(f'Uploaded {blob_name} to Azure Blob Storage successfully.')

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.