java - gstreamer 快速转码

标签 java clojure mp3 gstreamer amr

编辑 使用解决方案更新代码

我需要将 amr 转码为 mp3,所以我在 gstreamer-java 中编写了一个 gstreamer 管道。它看起来像这样:

src ! amrparse ! amrnbdec ! lamemp3enc ! sink 

(当然,实际上是用java API构建的),我用

开始转码
Bus.connect(EOS, fn(){Gst.quit();});

setState(PLAYING);
Gst.main();

它工作正常,除了它花费的时间等于音频长度,这是 Not Acceptable 。 等价

gst-launch 

以机器速度转码。

那么我需要如何设置管道才能获得机器速度转码?

这是完整的源代码,适合精通 clojure 的人

(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)))

最佳答案

为您的输出尝试 .setSync(false)。在普通的 gstreamer 中,同步流会尝试跟踪时间,而异步流会尽可能快地运行。也许您的输出流正在尝试实时工作。

关于java - gstreamer 快速转码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3903379/

相关文章:

java - indexOf() 具有重复字符串的奇怪 Java.util.List 行为

java - 我无法让 KeyEvent 监听器工作

java - OpenCV 3.0.0 JAR 中缺少 HighGUI

用于项目构建的 Ant/Ivy

mp3 - id3信息

ruby-on-rails - 回形针 validates_attachment_content_type 附加 mp3 时触发的 mp3

java - 使用 Java 8 安装 Dynamic Code Evolution VM (DCE) 时出错

java - 如何在 Sqlite 中搜索字符串值?

clojure - 在 Clojure 函数中重新绑定(bind) var 的具体缺点是什么?

c# - 将 PCM 转换为 MP3/OGG