Frage

Ich weiß, dass es hier einige ähnliche Fragen gibt, aber die meisten von ihnen sind die Erzeugung von Wellenform Bilder, was nicht das ist, was ich will.

Mein Ziel ist es, eine Wellenformvisualisierung für eine Audio -Datei zu erzeugen, ähnlich wie SoundCloud, aber kein Bild. Ich möchte die maximalen Amplitudendaten für jede Sekunde (oder halbe Sekunde) eines Audioclips in einem Array haben. Ich könnte diese Daten dann verwenden, um eine CSS-basierte Visualisierung zu erstellen.

Idealerweise möchte ich ein Array erhalten, das alle Amplitudenwerte für jede Sekunde als Prozentsatz der maximalen Amplitude der gesamten Audiodatei aufweist. Hier ist ein Beispiel:

[
    0.0,  # Relative max amplitude of first second of audio clip (0%)
    0.04,  # Relative max amplitude of second second of audio clip (4%)
    0.15,  # Relative max amplitude of third second of audio clip (15%)
    # Some more
    1.0,  # The highest amplitude of the whole audio clip will be 1.0 (100%)
]

Ich nehme an numpy und Python wave Modul, aber ich bin mir nicht sicher, wie ich die gewünschten Daten erhalten kann. Ich möchte Python verwenden, aber ich bin nicht ganz dagegen, ein Befehlszeilen-Tool zu verwenden.

War es hilfreich?

Lösung

Wenn Sie Gstreamer zulassen, ist hier ein kleines Skript, das den Trick ausführen könnte. Es akzeptiert jede Audiodatei, die Gstreamer verarbeiten kann.

  • Konstruieren Sie eine Gstreamer -Pipeline, verwenden Sie Audioconvert, um die Kanäle auf 1 zu reduzieren, und verwenden Sie das Level -Modul, um Peaks zu erhalten
  • Führen Sie die Pipeline aus, bis EOS getroffen wird
  • Normalisieren Sie die Peaks von min/max gefunden.

Snippet:

import os, sys, pygst
pygst.require('0.10')
import gst, gobject
gobject.threads_init()

def get_peaks(filename):
    global do_run

    pipeline_txt = (
        'filesrc location="%s" ! decodebin ! audioconvert ! '
        'audio/x-raw-int,channels=1,rate=44100,endianness=1234,'
        'width=32,depth=32,signed=(bool)True !'
        'level name=level interval=1000000000 !'
        'fakesink' % filename)
    pipeline = gst.parse_launch(pipeline_txt)

    level = pipeline.get_by_name('level')
    bus = pipeline.get_bus()
    bus.add_signal_watch()

    peaks = []
    do_run = True

    def show_peak(bus, message):
        global do_run
        if message.type == gst.MESSAGE_EOS:
            pipeline.set_state(gst.STATE_NULL)
            do_run = False
            return
        # filter only on level messages
        if message.src is not level or \
           not message.structure.has_key('peak'):
            return
        peaks.append(message.structure['peak'][0])

    # connect the callback
    bus.connect('message', show_peak)

    # run the pipeline until we got eos
    pipeline.set_state(gst.STATE_PLAYING)
    ctx = gobject.gobject.main_context_default()
    while ctx and do_run:
        ctx.iteration()

    return peaks

def normalize(peaks):
    _min = min(peaks)
    _max = max(peaks)
    d = _max - _min
    return [(x - _min) / d for x in peaks]

if __name__ == '__main__':
    filename = os.path.realpath(sys.argv[1])
    peaks = get_peaks(filename)

    print 'Sample is %d seconds' % len(peaks)
    print 'Minimum is', min(peaks)
    print 'Maximum is', max(peaks)

    peaks = normalize(peaks)
    print peaks

Und ein Ausgangsbeispiel:

$ python gstreamerpeak.py 01\ Tron\ Legacy\ Track\ 1.mp3 
Sample is 182 seconds
Minimum is -349.999999922
Maximum is -2.10678956719
[0.0, 0.0, 0.9274581631597019, 0.9528318436488018, 0.9492396611762614,
0.9523404330322813, 0.9471685835966183, 0.9537281219301242, 0.9473486577135167,
0.9479292126411365, 0.9538221105563514, 0.9483845795252251, 0.9536790832823281,
0.9477264933378022, 0.9480077366961968, ...
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top