2013-10-22 2 views
0

자동으로 동영상을 압축하고 싶습니다. 그래서 파이썬에서 mediainfo 래퍼 클래스를 작성하여 xml 출력을 생성 한 다음 오디오 및 자막 트랙 목록이있는 movieinfo 클래스로 파싱합니다.Python이 정렬 목록 생성

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의 관련 정보를 구문 분석 : 여기

__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 클래스의)입니다.

이제 오디오 트랙 목록이 있습니다. 예 : 독일어와 AC3에서 하나, 영어와 AC3에서 하나씩 독일어 언어와 DTS에서 3 트랙. 이제는 "1,2,3"형식으로 트랙에서 ID를 가져 와서 핸드 브레이크를 제공하려고합니다.

내 문제는 트랙 순서입니다. 독일어 DTS 트랙이있는 경우이 트랙이 첫 번째 트랙이어야하며 두 번째 트랙도 첫 번째 트랙이어야하고 AAC로 압축되어야하고 세 번째 트랙은 AAC의 한 영어 트랙이어야합니다. 독일어 AC3 트랙이있는 경우 첫 번째 트랙은이 트랙이어야하지만 AAC로 압축되어야하며 두 번째 트랙은 AAC로 인코딩되어야합니다. 나는 그것이 어떻게 생존 할 수 있는지 정확히 알지 못한다. 나를 도와 줄 수 있니? 저는 Python을 처음 사용하고 C, C++ 및 C#에서 왔습니다. C#에서는 람다를 사용하는 것이 매우 쉽습니다.

답변

0

두 항목이 어느 것이 더 큰지, 그리고 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

정렬 도구가 너무 강력하다는 점에 감사드립니다. 즉, 나는 독일인이 영어보다 크고 AC3보다 큰 DTS를 정의하는 비교자를 생성한다는 것을 의미합니다. – Dominik2000