EDITUpdated code with solution
GStreamer transcode rapide
Je dois transcoder amr mp3, donc je l'ai écrit un pipeline dans GStreamer GStreamer-java. Il ressemble à ceci:
src ! amrparse ! amrnbdec ! lamemp3enc ! sink
(en fait construit avec l'API java, bien sûr), je commence le transcoder avec
Bus.connect(EOS, fn(){Gst.quit();});
setState(PLAYING);
Gst.main();
Il fonctionne très bien, sauf le temps qu'il faut est égale à l'audio longueur, ce qui n'est pas acceptable. L'équivalent
gst-launch
transcode à la vitesse de la machine.
Alors, comment dois-je configurer le pipeline, pour obtenir le transcodage de la vitesse de la machine?
est ici la source complète, pour les personnes avec clojure couramment
(ns audio
(:import [org.gstreamer Gst Pipeline Bin Element ElementFactory State
StateChangeReturn Bus$EOS Bus$ERROR Bus$STATE_CHANGED]
[org.gstreamer.io InputStreamSrc OutputStreamSink]
[java.io InputStream OutputStream])
(:use clojure.contrib.logging))
(Gst/init)
(defn transcode [^InputStream in ^OutputStream out]
(let [id (gensym (quote transcode))
src (InputStreamSrc. in (str "in stream " id))
dec0 (ElementFactory/make "amrparse" (str "amr parser " id))
dec1 (ElementFactory/make "amrnbdec" (str "amr decoder " id))
enc (doto (ElementFactory/make "lamemp3enc" (str "mp3 encoder " id))
(.set "mono" true)
(.set "target" 0)
(.set "quality" 2))
out (doto (OutputStreamSink. out (str "out stream " id))
(.setSync false))
pipe (doto (Pipeline. (str "transcoder pipe " id))
(.add src)
(.add dec0)
(.add dec1)
(.add enc)
(.add out))
clean (fn []
(.setState src nil)
(.setState dec0 nil)
(.setState dec1 nil)
(.setState enc nil)
(.setState out nil)
(.setState pipe nil))]
(prn "starting transcode " id)
(.link src dec0)
(.link dec0 dec1)
(.link dec1 enc)
(.link enc out)
(doto (.getBus pipe)
(.connect
(reify Bus$EOS
(endOfStream [this src]
(prn "Bus finished " src)
(clean)
(Gst/quit))))
(.connect
(reify Bus$ERROR
(errorMessage [this src code msg]
(prn "Bus Error " src code msg)
(clean)
(Gst/quit))))
(.connect
(reify Bus$STATE_CHANGED
(stateChanged [this src old now pending]
(prn "Bus State change " src old now pending)))))
(.setState pipe State/PLAYING)
(Gst/main)))
Parfait! C'était juste ce que je cherchais. Maintenant, je peux revenir sur le hack Shell Script :) Merci beaucoup! Pouvez-vous me dire où chercher cette information? Et pourquoi seulement le flux de sortie bloque, mais pas par ex. le flux d'entrée ou le pipeline lui-même? – Bendlas
La sortie définit généralement le débit (la carte son) pour l'ensemble du pipeline. Pour quelque raison que ce soit, les bindings Java mettent cela à true, peut-être parce que c'est un flux io générique pas forcément un fichier, mais 'gst-launch ...! filesink' irait vite avec sync automatiquement false. Je ne sais pas où chercher ceci en plus de deviner à quoi servent les propriétés gst-inspect. – joeforker