gpt4 book ai didi

python-3.x - AttributeError : 'str' object has no attribute 'write' , youtube-dl kivy

转载 作者:行者123 更新时间:2023-12-05 05:01:52 36 4
gpt4 key购买 nike

我目前正在做一个需要 youtube-dl 才能在 kivy 环境中工作的小项目。我有 python 3.8.3、Kivy 1.11.1、youtube-dl 2020.5.8。除了这个问题,kivy 在 python3.8 上运行良好。

我在尝试使用 youtube-dl 获取有关 youtube 视频的信息时收到此错误 AttributeError: 'str' object has no attribute 'write'

它确实适用于少数链接,但不适用于许多其他链接。

此错误已出现在 youtube-dl 的 github 页面 [[此处]][1] 上,但我找不到任何解决方案。

以下是两个具有可重现示例的案例。

案例一

import youtube_dl
from kivy.app import App
from kivy.uix.button import Button


class MusicApp(App):
def build(self):
return Button(text='Example')


ydl_opts = {
'outtmpl': '%(title)s.%(ext)s',
'audio-format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(['https://www.youtube.com/watch?v=BaW_jenozKc'])

输出

[INFO   ] [Logger      ] Record log in /home/adarsh/.kivy/logs/kivy_20-06-23_1.txt
[INFO ] [Kivy ] v1.11.1
[INFO ] [Kivy ] Installed at "/usr/local/lib/python3.8/dist-packages/kivy/__init__.py"
[INFO ] [Python ] v3.8.2 (default, Apr 27 2020, 15:53:34)
[GCC 9.3.0]
[INFO ] [Python ] Interpreter at "/usr/bin/python3"
[INFO ] [Factory ] 184 symbols loaded
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil, img_gif (img_ffpyplayer ignored)
[INFO ] [Text ] Provider: sdl2(['text_pango'] ignored)
[youtube] BaW_jenozKc: Downloading webpage
[download] Resuming download at byte 215799
[download] Destination: youtube-dl test video ''_ä↭𝕐.f137.mp4
[download] 100% of 2.11MiB in 00:07.90KiB/s ETA 00:00
[download] Destination: youtube-dl test video ''_ä↭𝕐.f140.m4a
[download] 100% of 154.06KiB in 00:00.07KiB/s ETA 00:00
[ffmpeg] Merging formats into "youtube-dl test video ''_ä↭𝕐.mp4"
Deleting original file youtube-dl test video ''_ä↭𝕐.f137.mp4 (pass -k to keep)
Deleting original file youtube-dl test video ''_ä↭𝕐.f140.m4a (pass -k to keep)
[ffmpeg] Destination: youtube-dl test video ''_ä↭𝕐.mp3
Deleting original file youtube-dl test video ''_ä↭𝕐.mp4 (pass -k to keep)

案例二

import youtube_dl
from kivy.app import App
from kivy.uix.button import Button


class MusicApp(App):
def build(self):
return Button(text='Example')


ydl_opts = {
'outtmpl': '%(title)s.%(ext)s',
'audio-format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(['https://www.youtube.com/watch?v=nTj4wVJAbNg'])

输出

[INFO   ] [Logger      ] Record log in /home/adarsh/.kivy/logs/kivy_20-06-23_2.txt
[INFO ] [Kivy ] v1.11.1
[INFO ] [Kivy ] Installed at "/usr/local/lib/python3.8/dist-packages/kivy/__init__.py"
[INFO ] [Python ] v3.8.2 (default, Apr 27 2020, 15:53:34)
[GCC 9.3.0]
[INFO ] [Python ] Interpreter at "/usr/bin/python3"
[INFO ] [Factory ] 184 symbols loaded
[INFO ] [Image ] Providers: img_tex, img_dds, img_sdl2, img_pil, img_gif (img_ffpyplayer ignored)
[INFO ] [Text ] Provider: sdl2(['text_pango'] ignored)
[youtube] nTj4wVJAbNg: Downloading webpage
Traceback (most recent call last):
File "temp/tmp.py", line 21, in <module>
ydl.download(['https://www.youtube.com/watch?v=nTj4wVJAbNg'])
File "/home/adarsh/.local/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 2018, in download
res = self.extract_info(
File "/home/adarsh/.local/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 808, in extract_info
return self.process_ie_result(ie_result, download, extra_info)
File "/home/adarsh/.local/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 863, in process_ie_result
return self.process_video_result(ie_result, download=download)
File "/home/adarsh/.local/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 1644, in process_video_result
self.process_info(new_info)
File "/home/adarsh/.local/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 1902, in process_info
self.report_warning(
File "/home/adarsh/.local/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 613, in report_warning
self.to_stderr(warning_message)
File "/home/adarsh/.local/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 527, in to_stderr
self._write_string(output, self._err_file)
File "/home/adarsh/.local/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 506, in _write_string
write_string(s, out=out, encoding=self.params.get('encoding'))
File "/home/adarsh/.local/lib/python3.8/site-packages/youtube_dl/utils.py", line 3174, in write_string
out.buffer.write(byt)
AttributeError: 'str' object has no attribute 'write'

即使有一些解决方法,也请提出建议。

编辑:我将记录器传递给了从他们的 github 页面获取的 youtube-dl

class MyLogger(object):
def debug(self, msg):
print("DEBUG " + msg)
pass

def warning(self, msg):
print("WARNING " + msg)
pass

def error(self, msg):
print("ERROR " + msg)

我需要稍后编写自己的记录器来获取下载进度。所以我要使用这个解决方案。[1]: https://github.com/ytdl-org/youtube-dl/issues/22109

最佳答案

我正在做一个类似的项目,但遇到了同样的错误。

我捕获异常并打印回溯

import traceback

...

try:
with youtube_dl.YoutubeDL(self.ydl_opts) as ydl:
ydl.download([self.url])
except Exception as inst:
print(inst)
tb = traceback.format_exc()
print(tb)
pass

我得到了这个:

'str' object has no attribute 'write'
Traceback (most recent call last):
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/YoutubeDL.py", line 797, in extract_info
ie_result = ie.extract(url)
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/extractor/common.py", line 530, in extract
ie_result = self._real_extract(url)
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/extractor/generic.py", line 2277, in _real_extract
% (url, url), expected=True)
youtube_dl.utils.ExtractorError: 'qsd' is not a valid URL. Set --default-search "ytsearch" (or run youtube-dl "ytsearch:qsd" ) to search YouTube

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "src/main.py", line 81, in run
download_retcode = ydl.download([self.url])
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/YoutubeDL.py", line 2019, in download
url, force_generic_extractor=self.params.get('force_generic_extractor', False))
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/YoutubeDL.py", line 820, in extract_info
self.report_error(compat_str(e), e.format_traceback())
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/YoutubeDL.py", line 625, in report_error
self.trouble(error_message, tb)
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/YoutubeDL.py", line 578, in trouble
self.to_stderr(message)
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/YoutubeDL.py", line 527, in to_stderr
self._write_string(output, self._err_file)
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/YoutubeDL.py", line 506, in _write_string
write_string(s, out=out, encoding=self.params.get('encoding'))
File "/home/odrevet/.local/lib/python3.6/site-packages/youtube_dl/utils.py", line 3180, in write_string
out.buffer.write(byt)
AttributeError: 'str' object has no attribute 'write'

通过查看堆栈中函数的名称,我们可以看到当 ytdl 尝试报告另一个错误时我们的错误发生了(在这种情况下:“youtube_dl.utils.ExtractorError:‘qsd’不是有效的 URL”,因为我在我的程序中输入了“qsd”而不是有效的 url)。

通过查看 YoutubeDl.py 中的 to_stderr 函数,我们可以看到 out 应该是 sys.stderr,而在 utils.py 中发生错误的函数中:

def write_string(s, out=None, encoding=None):
print(type(out)) # I added this line
if out is None:
out = sys.stderr
assert type(s) == compat_str

if sys.platform == 'win32' and encoding is None and hasattr(out, 'fileno'):
if _windows_write_string(s, out):
return

if ('b' in getattr(out, 'mode', '')
or sys.version_info[0] < 3): # Python 2 lies about mode of sys.stderr
byt = s.encode(encoding or preferredencoding(), 'ignore')
out.write(byt)
elif hasattr(out, 'buffer'):
enc = encoding or getattr(out, 'encoding', None) or preferredencoding()
byt = s.encode(enc, 'ignore')
out.buffer.write(byt) # Error on line 3180
else:
out.write(s)
out.flush()

根据 hasattr elif 检查,stderr 有一个缓冲区属性,问题是 Kivy 如何处理错误流。根据我在 write_string 中添加的打印,stderr 被重新定义为一个 ,它确实有一个缓冲区属性,就像它应该的流一样,但这个属性是一个简单的字符串。

参见 https://kivy.org/doc/stable/_modules/kivy/logger.html

class LogFile(object):

def __init__(self, channel, func):
self.buffer = '' # <-- a str
self.func = func
self.channel = channel
self.errors = ''

我不知道是否可以通过参数化 kivy 来为 stderr 使用标准流,但我会检查一下。同时捕获异常并打印回溯以至少在“处理上述异常期间,发生另一个异常”之前有原始错误

编辑:您可以将 stderr 重定向到一个文件

sys.stderr = open('./stderr', 'w')

关于python-3.x - AttributeError : 'str' object has no attribute 'write' , youtube-dl kivy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62525458/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com