Python生成排序列表

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

我想自动压缩我的电影。因此,我用python编写了一个mediainfo包装类,以生成xml输出,然后将其解析为一个movieinfo类,其中包含音频和字幕曲目列表

__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