Python生成排序列表
我想自动压缩我的电影。因此,我用python编写了一个mediainfo包装类,以生成xml输出,然后将其解析为一个movieinfo类,其中包含音频和字幕曲目列表Python生成排序列表,python,list,mediainfo,Python,List,Mediainfo,我想自动压缩我的电影。因此,我用python编写了一个mediainfo包装类,以生成xml输出,然后将其解析为一个movieinfo类,其中包含音频和字幕曲目列表 __author__ = 'dominik' class Error(Exception): """ Error class """ class ValidationError(Error): """ Invalid or missing xml items """ class Movie
__author__ = 'dominik'
class Error(Exception):
""" Error class
"""
class ValidationError(Error):
""" Invalid or missing xml items
"""
class MovieInfo(object):
""" Description of movie file
"""
def __init__(self, media_info):
self._video_track = None
self._audio_tracks = []
self._subtitle_tracks = []
self.valid_movie = True
for track in media_info.tracks:
if track.track_type == "Audio":
self._audio_tracks.append(AudioTrack(track))
elif track.track_type == "Text":
self._subtitle_tracks.append(SubtitleTrack(track))
elif track.track_type == "Video":
self._video_track = VideoTrack(track)
@property
def audio_tracks(self):
if not hasattr(self, "_audio_tracks"):
self._audio_tracks = []
if len(self._audio_tracks) != 0:
return self._audio_tracks
@property
def subtitle_tracks(self):
if not hasattr(self, "_subtitle_tracks"):
self._subtitle_tracks = []
if len(self._subtitle_tracks) != 0:
return self._subtitle_tracks
class Track(object):
""" Abstract track class for audio and subtitle tracks
"""
__KNOWN_LANGUAGE_CODES = {"en": "ENG", "de": "DE"}
def __init__(self, track, valid_codecs):
self._valid = True
track_id = int(track.id)
codec_id = self._determine_codec(track.codec_id, valid_codecs)
language = self._determine_language(track.language)
self._id = track_id
self._codec_id = codec_id
self._language = language
def _determine_codec(self, track_codec, types):
result = types.get(track_codec, None)
if result is None:
self._valid = False
return result
def _determine_language(self, track_language, types=__KNOWN_LANGUAGE_CODES):
result = types.get(track_language, None)
if result is None:
self._valid = False
return result
class AudioTrack(Track):
""" Audio track class
"""
__KNOWN_AUDIO_CODECS = {"A_DTS": "DTS", "A_AC3": "AC3"}
def __init__(self, track):
self._type = 1
Track.__init__(self, track, self.__KNOWN_AUDIO_CODECS)
class SubtitleTrack(Track):
""" Subtitle track class
"""
__KNOWN_SUBTITLE_CODECS = {"S_VOBSUB": "VOBSUB"}
def __init__(self, track):
self._type = 2
if track.forced == "Yes":
self._forced = True
else:
self._forced = False
Track.__init__(self, track, self.__KNOWN_SUBTITLE_CODECS)
class VideoTrack(object):
""" Video track class (only one video track in movie info!)
"""
def __init__(self, track):
self._type = 0
self._framerate = float(track.frame_rate)
self._width = track.width
self._height = track.height
以下是mediainfo类(它是pymediainfo类):
从子流程导入Popen
导入操作系统
从tempfile导入mkstemp
来自bs4进口美化集团,NavigableString
从setuptools.compat导入unicode
类轨迹(对象):
“”“保留曲目信息。”
"""
def _uGetAttr _;(自身,项目):
尝试:
返回对象。获取属性(自身,项)
除:
通过
一无所获
定义初始化(自我,xml跟踪):
self.xml\u track=xml\u track
self.track\u type=xml\u track.attrs[“type”]
对于self.xml_track.children中的子项:
如果不存在(子项、导航提示):
node_name=child.name.lower().strip()
node_value=unicode(child.string)
node\u other\u name=“other\u%s”%node\u name
如果getattr(self,node_name)为无:
setattr(自身、节点名称、节点值)
其他:
如果getattr(自身、节点\其他\名称)为无:
setattr(自身,节点\其他\名称,[节点\值,])
其他:
getattr(self,node\u other\u name).append(node\u value)
对于输入[c为c为c的输入,如果c.startswith(“其他”)]:
尝试:
primary=key.replace(“其他”,“”)
setattr(self,primary,int(getattr(self,primary)))
除:
对于getattr中的值(self,key):
尝试:
实际值=getattr(自、主)
setattr(自、主、int(值))
getattr(self,key).append(实际)
打破
除:
通过
定义报告(自我):
返回(“.”格式(self.id,self.track_type))
def至_数据(自身):
数据={}
对于k,v,在self.dict.items()中:
如果k!='xml_track':
数据[k]=v
返回数据
类Mediainfo(对象):
“”“MediaInfo包装器”
"""
定义初始化(self,xml):
self.xml_dom=xml
如果isinstance(xml、str):
self.xml_dom=BeautifulSoup(xml,“xml”)
def_填充_轨迹(自):
如果self.xml_dom为无:
返回
对于self.xml\u dom.Mediainfo.File.find\u all(“track”)中的xml\u track:
self.\u tracks.append(Track(xml\u Track))
@财产
def轨迹(自):
如果不是hasattr(self,“\u跟踪”):
self._轨道=[]
如果len(self.\u轨迹)==0:
self.\u填充\u轨迹()
返回自我
@静力学方法
def解析(文件名):
filehandler\u out,filename\u out=mkstemp(“.xml”,“mediainfo-”)
filehandler\u err,filename\u err=mkstemp(“.error”,“mediainfo-”)
filepointer\u out=os.fdopen(filehandler\u out,“r+b”)
filepointer\u err=os.fdopen(filehandler\u err,“r+b”)
mediainfo\u命令=[“mediainfo”,“-f”,“--Output=XML”,文件名]
p=Popen(mediainfo\u命令,stdout=filepointer\u out,stderr=filepointer\u err)
p、 等等
文件指针_out.seek(0)
xml\u dom=BeautifulSoup(filepointer\u out.read(),“xml”)
filepointer_out.close()
filepointer_err.close()
打印(xml_dom)
返回Mediainfo(xml_dom)
def至_数据(自身):
数据={'tracks':[]}
对于self.tracks中的轨迹:
数据['tracks'].append(track.to_data())
返回数据
这个类给我xml中的每一首曲目,然后我解析movieinfo中的相关信息
好的,现在我有一个音频曲目列表,例如3首曲目,一首是德语和DTS,一首是德语和AC3,另一首是英语和AC3。现在我想以“1,2,3”格式从曲目中获取ID,以将其提供给handbrake cli
我的问题是轨道的顺序。如果有德国DTS音轨,该音轨应为第一音轨,第二音轨也应为第一音轨,但压缩为aac,第三音轨应为aac中的一条英语音轨。如果只有德语AC3音轨,则第一个音轨应为该音轨,但压缩为AAC,第二个音轨应为英语和AAC。
我不知道怎么才能做到,你能帮我吗?我是Python的新手,来自C、C++和C语言。在C语言中,这是很容易得到的lambda。< p>假设你知道定义一个比较器,给定两个项可以定义哪个比Python函数大,也可以定义为C或C++。 从这里开始- 1.
使用排序方法并定义所需的键。谢谢,我不知道,排序工具是如此强大。这意味着我生成了一个比较器,它定义了德语大于英语,DTS大于AC3。
from subprocess import Popen
import os
from tempfile import mkstemp
from bs4 import BeautifulSoup, NavigableString
from setuptools.compat import unicode
class Track(object):
""" Hold the track information
"""
def __getattr__(self, item):
try:
return object.__getattribute__(self, item)
except:
pass
return None
def __init__(self, xml_track):
self.xml_track = xml_track
self.track_type = xml_track.attrs["type"]
for child in self.xml_track.children:
if not isinstance(child, NavigableString):
node_name = child.name.lower().strip()
node_value = unicode(child.string)
node_other_name = "other_%s" % node_name
if getattr(self, node_name) is None:
setattr(self, node_name, node_value)
else:
if getattr(self, node_other_name) is None:
setattr(self, node_other_name, [node_value, ])
else:
getattr(self, node_other_name).append(node_value)
for key in [c for c in self.__dict__.keys() if c.startswith("other_")]:
try:
primary = key.replace("other_", "")
setattr(self, primary, int(getattr(self, primary)))
except:
for value in getattr(self, key):
try:
actual = getattr(self, primary)
setattr(self, primary, int(value))
getattr(self, key).append(actual)
break
except:
pass
def __repr__(self):
return("<Track id='{0}', type='{1}'>".format(self.id, self.track_type))
def to_data(self):
data = {}
for k, v in self.__dict__.items():
if k != 'xml_track':
data[k] = v
return data
class Mediainfo(object):
""" MediaInfo wrapper
"""
def __init__(self, xml):
self.xml_dom = xml
if isinstance(xml, str):
self.xml_dom = BeautifulSoup(xml, "xml")
def _populate_tracks(self):
if self.xml_dom is None:
return
for xml_track in self.xml_dom.Mediainfo.File.find_all("track"):
self._tracks.append(Track(xml_track))
@property
def tracks(self):
if not hasattr(self, "_tracks"):
self._tracks = []
if len(self._tracks) == 0:
self._populate_tracks()
return self._tracks
@staticmethod
def parse(filename):
filehandler_out, filename_out = mkstemp(".xml", "mediainfo-")
filehandler_err, filename_err = mkstemp(".error", "mediainfo-")
filepointer_out = os.fdopen(filehandler_out, "r+b")
filepointer_err = os.fdopen(filehandler_err, "r+b")
mediainfo_command = ["mediainfo", "-f", "--Output=XML", filename]
p = Popen(mediainfo_command, stdout=filepointer_out, stderr=filepointer_err)
p.wait()
filepointer_out.seek(0)
xml_dom = BeautifulSoup(filepointer_out.read(), "xml")
filepointer_out.close()
filepointer_err.close()
print(xml_dom)
return Mediainfo(xml_dom)
def to_data(self):
data = {'tracks': []}
for track in self.tracks:
data['tracks'].append(track.to_data())
return data