2016-09-15 53 views
1

我想使用videofileclip(),但會發生UnicodeDecodeError。 視頻文件包括日文漢字或特殊字符。使用Python unicode的特殊字符/漢字問題

我的示例代碼:

#-*- coding: utf-8 -*- 
import sys 
from moviepy.editor import VideoFileClip 

reload(sys) 
sys.setdefaultencoding('utf-8') 

a='H:\\kittens.mkv' 
clip1=VideoFileClip(a) 

b='H:\\「ēī①」.mp4' 
clip2=VideoFileClip(b) 

if clip1.fps >= clip2.fps: 
    os.remove(b) 
else: 
    os.remove(a)   

'一個' 正常工作:

>>> a='H:\\kittens.mkv' 
>>> clip=VideoFileClip(a) 
>>> 

但 'B' 不起作用:

>>> b='H:\\「ēī①」.mp4' 
>>> clip=VideoFileClip(b) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python27\lib\site-packages\moviepy\video\io\VideoFileClip.py", line 5 
5, in __init__ 
    reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt) 
    File "C:\Python27\lib\site-packages\moviepy\video\io\ffmpeg_reader.py", line 3 
2, in __init__ 
    infos = ffmpeg_parse_infos(filename, print_infos, check_duration) 
    File "C:\Python27\lib\site-packages\moviepy\video\io\ffmpeg_reader.py", line 2 
70, in ffmpeg_parse_infos 
    filename, infos)) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa1 in position 54: invalid 
start byte 
>>> b 
'H:\\\xa1\xb0??\xa8\xe7\xa1\xb1.mp4' 
>>> print b 
H:\「??①」.mp4 
>>> print b.decode('cp949') 
H:\「??①」.mp4 
>>> 

我試過這個,但它也不起作用。

b=b.decode('cp949') 
b=b.decode('cp949').encode('utf-8') 
b=unicode(b.decode('cp949')) 

我認爲Windows 7的支持Unicode文件名(在日本漢字或特殊字符),但(CP949)字符集的Python(2.X)不支持特殊字符。我能爲這個問題做些什麼?

+0

我懷疑這不是你的代碼不支持unicode,而是模塊'moviepy'。我記得有一個技巧可以避免這種情況,我會盡力找到它。 – FunkySayu

+0

謝謝。我在等你的幫助。 – User8392

+1

它可能不是這個特定的問題,但[爲什麼sys.setdefaultencoding會破壞代碼](https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/)。這是從來沒有需要的,有一個原因,它不能沒有'重新加載(sys)'技巧調用。去掉它。也可以嘗試一個Unicode字符串,而不是文件名的字節字符串,例如'u'H:\\「ēī①」 .mp4''。確保將源文件保存在UTF-8的聲明源編碼中。 'b'目前是以UTF-8編碼的字節串,這在Windows中是一個不太可能的文件名。 –

回答

0

以下是使用pywin32擴展的解決方法。 基本上,您使用GetShortPathName函數從unicode路徑生成傳統8.3 filename

# -*- coding: utf-8 -*- 

import os 
import win32api 
from moviepy.editor import VideoFileClip 


def short_path(unicode_path): 
    return win32api.GetShortPathName(unicode_path) 


v1 = '「ēī①」.mp4' 
print os.path.isfile(v1) # False 

v2 = u'「ēī①」.mp4' 
print os.path.isfile(v2) # True 

# clip = VideoFileClip(v1) # IOError 
# clip = VideoFileClip(v2) # UnicodeEncodeError 
clip = VideoFileClip(short_path(v2)) # OK 
print clip.duration