Alle .ogg Dateien in mp3 umwandeln

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
keboo
User
Beiträge: 132
Registriert: Sonntag 19. Februar 2006, 14:03

Hallo Leute!

Kennt wer von euch eine Möglichkeit wie man über ein Python Skript alle .ogg Dateien in MP3 umwandeln kann?

Wär super.

Danke,

Johannes
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

sofern du mplayer oder ein anderes Mulittalent hast kannst du sie über die Kommandozeile ansteuern -> subprocess.
Ansonsten drüfte dir pymedia helfen, dass sollte das auch können.
TUFKAB – the user formerly known as blackbird
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Oder eine Kombi aus lame und oggenc, die sind auch praktisch. Eigentlich kann man das ganze dann auch als Shellscript schreiben, außer man will noch irgendwelche anderen tollen Sachen zusätzlich machen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
keboo
User
Beiträge: 132
Registriert: Sonntag 19. Februar 2006, 14:03

Hi!

Ich möchte alle ogg. Dateien aus einem Ordner in mp3s umwandeln.
Bei pymedia hab ich folgendes Skript entdeckt:

Code: Alles auswählen

#! /bin/env python

import sys, time, traceback

########################################################################3
# Simple  audio encoder 
def recodeAudio( fName, fOutput, type, bitrate= None ):
  # ------------------------------------

  import pymedia.audio.acodec as acodec
  import pymedia.muxer as muxer
  # Open demuxer

  dm= muxer.Demuxer( fName.split( '.' )[ -1 ].lower() )
  f= open( fName, 'rb' )
  s= f.read( 90000 )
  dec= enc= mx= None
  print 'Recoding %s into %s' % ( fName, fOutput )
  while len( s ):
    frames= dm.parse( s )
    if frames:
      for fr in frames:
        # Assume for now only audio streams

        if dec== None:
          # Open decoder

          dec= acodec.Decoder( dm.streams[ fr[ 0 ] ] )
          print 'Decoder params:', dm.streams[ fr[ 0 ] ]
        
        # Decode audio frame

        r= dec.decode( fr[ 1 ] )
        if r:
          if bitrate== None:
            bitrate= r.bitrate
          
          # Open muxer and encoder

          if enc== None:
            params= { 'id': acodec.getCodecID(type),
                      'bitrate': bitrate,
                      'sample_rate': r.sample_rate,
                      'channels': r.channels }
            print 'Encoder params:', params
            mx= muxer.Muxer( type )
            stId= mx.addStream( muxer.CODEC_TYPE_AUDIO, params )
            enc= acodec.Encoder( params )
            fw= open(fOutput, 'wb')
            ss= mx.start()
            fw.write(ss)
        
          enc_frames= enc.encode( r.data )
          if enc_frames:
            for efr in enc_frames:
              ss= mx.write( stId, efr )
              if ss:
                fw.write(ss)
    
    s= f.read( 100000 )
  
  f.close()
  
  if fw:
    if mx:
      ss= mx.end()
      if ss:
        fw.write(ss)
    fw.close()

# ----------------------------------------------------------------------------------

# Change the format of your compressed audio files to something different

# http://pymedia.org/

if __name__== '__main__':
  if len( sys.argv )< 4 or len( sys.argv )> 5:
    print "Usage: recode_audio.py <audio_input_file> <audio_output_file> <format_name> [ <bitrate> ]"
  else:
    if len( sys.argv )== 4:
      recodeAudio( sys.argv[1], sys.argv[2], sys.argv[3] )
    else:
      recodeAudio( sys.argv[1], sys.argv[2], sys.argv[3], int( sys.argv[4] )* 1000 )


Wie kann ich da mein Quell- und mein Zielfile bzw. den Type angeben?
Kann mir wer kur erklären was sys.argv macht? Das hab ich nicht ganz durchblickt in der Doku was es damit auf sich hat.

Danke für eure Hilfe.

Johannes
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Warum muß es umbedingt ein Python-Skript sein? Ich weiss, dass Gentoo mit einem mp32ogg-ebuild kommt, das ist ein Shell-Skript, was genau das macht was Du haben willst. Ich bin mir sicher dass Du mit ein bissel googeln genau das selbe für Deine Distribution der Wahl (oder auch Windows) findest...

Allemal einfacher als ein Skript verstehen zu müssen, was Du nicht selbst geschrieben hast und abändern willst...
--- Heiko.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

sys.arg ist der i-te Kommandozeilenparameter, den man einem Python-Skript uebergeben hat. (i>=1).
sys.arg[0] ist der Name des Skriptes.

Und wie man das Skript benutzt, steht doch in Zeile 80:

Code: Alles auswählen

print "Usage: recode_audio.py <audio_input_file> <audio_output_file> <format_name> [ <bitrate> ]"
keboo
User
Beiträge: 132
Registriert: Sonntag 19. Februar 2006, 14:03

Code: Alles auswählen

print "Usage: recode_audio.py <audio_input_file> <audio_output_file> <format_name> [ <bitrate> ]"
Versteh leider nicht ganz, wie man das Skript richtig ausführt.
Die Inputdatei ist 1.ogg und die outputdatei soll dann sein 1.mp3.

Wie geb ich das richtig ein?

Danke,
Johannes
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Probier mal:

Code: Alles auswählen

python recode_audio.py 1.mp3 1.ogg ogg
Oder, noch besser, lad Dir endlich mp32ogg runter, und benutz das. ;-) Das baut nämlich nicht nur den Musik-Stream in die OGGs, sondern auch die (möglicherweise vorhandenen) ID3-Tags.
--- Heiko.
keboo
User
Beiträge: 132
Registriert: Sonntag 19. Februar 2006, 14:03

Habs Python unter Windows laufen.
Kann sein, dass deshalb dein Befehl nicht funktioniert?

Gibts mp32ogg auch unter Windows?

Lg
Johannes
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

keboo hat geschrieben:Gibts mp32ogg auch unter Windows?
mp32ogg ist ein Perl Script. Sollte auch unter Windows funktionieren, unter Zuhilfenahme des Perl-interpreters.

Allerdings plädiere ich immer noch für lame & oggenc ;)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Vor einer halben Ewigkeit habe ich mal ein Skript geschrieben, das ``lame``, ``ogg123`` und ``ogginfo`` benutzt. Damals habe ich noch Java-Namenskonventionen verwendet. Igitt. :-)

Code: Alles auswählen

#!/usr/bin/env python
#-----------------------------------------------------------------------------
# Name:        ogg2mp3.py
# Purpose:     Convert Ogg Vorbis file to MP3.
#
# Author:      Marc 'BlackJack' Rintsch
#
# Created:     2004/01/02
# RCS-ID:      $Id: ogg2mp3.py $
# Copyright:   (c) 2004
# Licence:     GPL
#-----------------------------------------------------------------------------
import os

# TODO: Write some documentation.
# TODO: CommandLineBuilder with proper quoting of shell specials.
# TODO: Implement LameGenreList as singleton.
# TODO: Use upper and lower bitrate info from ``ogginfo`` if available.

_OGGINFO = 'ogginfo'
_LAME = 'lame'
_CONVERT = 'ogg123 -d wav -f - "%s"|lame -h %s - "%s"'


class LameGenres(dict):
    """Dictionary that maps genre names to integers.
    
    The dictionary will be populated with data by querying ``lame``
    for the genres it supports upon instanciation.
    """
    def __init__(self):
        dict.__init__(self)
        lamePipe = os.popen(_LAME + ' --genre-list')
        # each line has the form 'nnn genre name\n'
        for line in lamePipe:
            self[line[4:-1]] = int(line[:3].lstrip())
        lamePipe.close()

genres = LameGenres()


class OggInfo:
    """Some meta information about an Ogg Vorbis file.
    
    Needs the ``ogginfo`` executable from the vorbis tools.
    """
    
    def __init__(self, filename=None):
        """Read meta info from given file."""
        
        self.filename = filename    # Filename.
        self.channels = None        # Number of channels (stereo/mono).
        self.rate = None            # Sample rate.
        self.nominalBitrate = None  # The nominal bitrate (i.e. MP3 equivalent)
        self.averageBitrate = None  # The real average bitrate.
        self.tag = {}               # User comments.
        
        # If filename is given, read the meta info via ``ogginfo``.
        if filename:
            # TODO: Check if file exists.
            ogginfoPipe = os.popen(_OGGINFO + ' "'
                                   + filename.replace('"', '\\"') + '"')
            # Using iter() explicitly is neccesary to prevent bug #2 in
            # Python 2.2.
            ogginfoIterator = iter(ogginfoPipe)
            for line in ogginfoIterator:
                # TODO: Check if int(float()) is really neccesary all the time.
                if line.startswith('Channels: '):
                    self.channels = int(float(line[10:-1]))
                
                elif line.startswith('Rate: '):
                    self.rate = int(float(line[6:-1]))
                    
                elif line.startswith('Nominal bitrate: '):
                    self.nominalBitrate = \
                        int(float(line[17:-6].replace(',', '.')))
                
                elif line.startswith('User comments section follows'):
                    self._parseComments(ogginfoIterator)
                
                elif line.startswith('\tAverage bitrate: '):
                    self.averageBitrate = float(line[18:-6].replace(',', '.'))
                    
            ogginfoPipe.close()
            # TODO: Check if we know any bitrate at this point.
    
    def __str__(self):
        return 'filename: %r\nchannels: %r\nrate: %r\nnominal bitrate: %r\n' \
               'average bitrate: %r\ntag: %r' % \
               (self.filename, self.channels, self.rate, 
                self.nominalBitrate, self.averageBitrate, self.tag)
    
    def _parseComments(self, file):
        """Read and parse user comments up to first line which doesn't
        start with a tab character.
        
        Attention: The first non-comment line is read and therefore lost
        for further reading!
        """
        for line in file:
            if line.startswith('\t'):
                tagname, content = line.lstrip().split('=', 1)
                self.tag[tagname] = content[:-1]
            else:
                return
    
    def getBitrateOption(self):
        """Return the bitrate option for ``lame`` as string.
        
        If there's a nominal birate for this OggInfo then return
        the option for CBR otherwise the average bitrate and the
        ABR option.
        """
        assert self.nominalBitrate or self.averageBitrate
        
        if self.nominalBitrate:
            return '-b %d' % self.nominalBitrate
        else:
            return '--abr %.2f' % self.averageBitrate
        
    def getTagOptions(self):
        """Return the tag options for ``lame`` as string."""
        
        # Mapping of Vorbis comments to lame options.
        tag2opt = {'title': '--tt', 'artist': '--ta', 'album': '--tl',
                   'date': '--ty', 'comment': '--tc', 'tracknumber': '--tn',
                   'genre': '--tg'}
        opts = []
        # First the ones that can be used 1:1.
        for name in ('title', 'artist', 'album', 'date', 'tracknumber'):
            content = self.tag.get(name)
            if content:
                opts.append('%s "%s"' % (tag2opt[name],
                                         content.replace('"', '\\"')))
        
        # If there's no comment then add a shameless plug.  :-)
        content = self.tag.get('comment') or 'Converted with ogg2mp3.py'
        opt = tag2opt['comment']
        opts.append('%s "%s"' % (opt, content.replace('"', '\\"')))

        # The genre comment has to be a valid ID3 genre name.
        # TODO: Make this independent from upper/lowercase.
        content = self.tag.get('genre')
        opt = tag2opt['genre']
        if content:
            if content in genres:
                opts.append('%s "%s"' % (opt, content))
            else:
                pass    # TODO: add warning here
                
        return ' '.join(opts)

    def getLameOptions(self):
        """Return options for ``lame`` as string."""
        return ' '.join((self.getBitrateOption(), self.getTagOptions()))


def replaceExt(path, newExt):
    """Replace file extension."""
    return os.path.splitext(path)[0] + newExt
    

def main():
    import sys
    
    if len(sys.argv) < 2:
        sys.exit('Usage: ogg2mp3.py input.ogg')
    
    info = OggInfo(sys.argv[1])
    os.system(_CONVERT % (info.filename, info.getLameOptions(),
                          replaceExt(info.filename, '.mp3')))


if __name__ == '__main__':
    main()
Ich habe das dann nie weiter verfolgt und mir stattdessen lieber einen USB-Flash-Player gekauft, der Oggs abspielen kann. :-)
modelnine
User
Beiträge: 670
Registriert: Sonntag 15. Januar 2006, 18:42
Wohnort: Celle
Kontaktdaten:

Damals habe ich noch Java-Namenskonventionen verwendet. Igitt.
Sach nix! Ich benutz die immer noch, obwohl ich jetzt Java seit sieben Jahre nicht mehr angefasst hab. ;-)
--- Heiko.
Antworten