【Python小技巧】moviepy读取字幕srt文件报错‘gbk‘ codec can‘t decode的解决办法(修改subtitles.py中SubtitlesClip类完美解决)


前言

最近研究moviepy,使用其给视频添加字幕,却发现一个很久不会碰到的问题----文件编码问题。这在python3.x很少发生了。不成想,moviepy还是有bug。

debug也是编程乐趣之一。不过写到这里,希望以后官方升级可以修复这个问题。

一、SubtitlesClip读取srt文件报错

报错信息如下:

    subtitles = SubtitlesClip(srt_path, generator)
  File "d:\ProgramData\anaconda3\envs\python38\lib\site-packages\moviepy\video\tools\subtitles.py", line 42, in __init__
    subtitles = file_to_subtitles(subtitles)
  File "d:\ProgramData\anaconda3\envs\python38\lib\site-packages\moviepy\video\tools\subtitles.py", line 154, in file_to_subtitles
    for line in f:
UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 54: illegal multibyte sequence

二、问题剖析

打开d:\ProgramData\anaconda3\envs\python38\lib\site-packages\moviepy\video\tools\subtitles.py
我这里是虚拟了一个python3.8的环境(每个人不一样),看报错信息即可知道文件在哪里。
根据以上报错信息,可以知道:

    def __init__(self, subtitles, make_textclip=None):
        
        VideoClip.__init__(self, has_constant_size=False)

        if isinstance(subtitles, str):
            subtitles = file_to_subtitles(subtitles)

42行,也就是最后一样,调用了154行。

    with open(filename,'r') as f:
        for line in f:

因为153行,with open(filename,‘r’) as f: 没有添加打开文件使用的编码,所以UTF-8格式的srt文件被Windows系统默认使用GBK模式打开,就出现了文章开通的报错提示了。

三、解决办法(2种)

这个问题很好解决,就是打开文件时增加编码格式就行。
(唉,这么low的bug)
如果srt文件都是utf-8编码格式,使用1方法即可解决。如果还有其它格式,可通过2方法完美解决。

1. 增加encoding='utf-8’的临时解决办法

    with open(filename,'r') as f:
        for line in f:

将以上修改如下,增加encoding='utf-8’即可。

    with open(filename,'r', encoding='utf-8') as f:
        for line in f:

2. 通过类初始化传递参数的终极解决办法

上面的方法,如果srt文件不是utf-8则也会报错,是否可以将其改为参数运行呢?

那当然可以啦!

不过,需要修改多个地方,分别在class定义的 init()参数里增加encoding=‘utf-8’,然后在调用函数将encoding进行传递;file_to_subtitles(filename)参数增加encoding,打开文件也增加。至此完成修改。目的就是在class初始化时就传递encoding参数,并层层调用后增加到with open(filename,‘r’, encoding=encoding) as f:这一行。

修改后的代码如下:

class SubtitlesClip(VideoClip):
    """ A Clip that serves as "subtitle track" in videos.
    
    One particularity of this class is that the images of the
    subtitle texts are not generated beforehand, but only if
    needed.

    Parameters
    ==========

    subtitles
      Either the name of a file, or a list

    Examples
    =========
    
    >>> from moviepy.video.tools.subtitles import SubtitlesClip
    >>> from moviepy.video.io.VideoFileClip import VideoFileClip
    >>> generator = lambda txt: TextClip(txt, font='Georgia-Regular', fontsize=24, color='white')
    >>> sub = SubtitlesClip("subtitles.srt", generator)
    >>> myvideo = VideoFileClip("myvideo.avi")
    >>> final = CompositeVideoClip([clip, subtitles])
    >>> final.write_videofile("final.mp4", fps=myvideo.fps)
    
    """

    def __init__(self, subtitles, make_textclip=None,encoding='utf-8'):
        
        VideoClip.__init__(self, has_constant_size=False)

        if isinstance(subtitles, str):
            subtitles = file_to_subtitles(subtitles,encoding=encoding)
def file_to_subtitles(filename,encoding):
    """ Converts a srt file into subtitles.

    The returned list is of the form ``[((ta,tb),'some text'),...]``
    and can be fed to SubtitlesClip.

    Only works for '.srt' format for the moment.
    """
    times_texts = []
    current_times = None
    current_text = ""
    with open(filename,'r', encoding=encoding) as f:

因为这里给类初始化赋值了encoding=‘utf-8’,所以默认是此格式的话,调用方法不加此参数一样可以使用,不会报错。如下:

sub = SubtitlesClip("subtitles.srt", generator)

如果是gbk的格式,才需要在类初始化时增加encoding参数,如下:

sub = SubtitlesClip("subtitles.srt", generator, encoding='gbk')

总结

以前python2.x文字编码老是各种出错,改用python3.x后,编码及中文问题都得到了解决。不曾想还是会应为编码问题倒是文件打不开或者乱码。

UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 54: illegal multibyte sequence

以后看到这个提示,先检查字符编码。然后就是打开方式,通常都可以解决。

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT里的交易员

分享是一种快乐,打赏是一种肯定

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值