2013-10-22 197 views
0

我想自動壓縮我的電影。所以我在python中編寫了一個mediainfo包裝類,以生成一個xml輸出,然後我將它解析爲一個movieinfo類,並帶有一個音頻和字幕軌道列表。Python生成排序列表

__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類):

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 

此類給我每個軌道中的XML,然後我在解析的movieinfo相關信息。

好吧,現在我有一個音頻記錄列表,例如, 3個跟蹤德語和DTS中的一個,德語和AC3中的一個以及英語和AC3中的一個。現在我想從格式爲「1,2,3」的軌道中獲取ID,並將其傳遞給手剎cli。

我的問題是曲目的順序。如果有德國的DTS音軌,這首歌曲應該是第一首歌曲,第二首歌曲應該也是第一首歌曲,但是壓縮到AAC,第三首歌曲應該是AAC的一首英文歌曲。如果只有德國的AC3音軌,那麼第一首歌曲應該是這首歌曲,但是被壓縮爲AAC,第二首歌曲應該是AAC。 我不知道我能如何存檔,你能幫我嗎?我是python新手,來自C,C++和C#。在C#中,使用lambda非常容易。

回答

0

假設你知道定義一個比較器,給定兩個項目可以定義哪個更大,然後Python函數以及C或C++。這裏

開始 - 1. https://wiki.python.org/moin/HowTo/Sorting/

  1. https://developers.google.com/edu/python/sorting

  2. http://docs.python.org/2/library/functions.html#sorted

使用排序方法和定義所需的關鍵。

+0

謝謝,我不知道,排序工具是如此強大。這意味着我生成一個比較器,它定義德語比英語更大,DTS比AC3更大。 – Dominik2000