3

FFMPEGが.webmファイルをサポートしているため、Xugglerを使用して.movファイルを.webmに変換しようとしています。

これは私のコードです:

    IMediaReader reader = ToolFactory.makeReader("/home/user/vids/2.mov");
    reader.addListener(ToolFactory.makeWriter("/home/user/vids/2.webm", reader));
    while (reader.readPacket() == null);
    System.out.println( "Finished" );

これを実行すると、次のエラーが発生します。

[main] ERROR org.ffmpeg - [libvorbis @ 0x8d7fafe0] Specified sample_fmt is not supported.
[main] WARN  com.xuggle.xuggler - Error: could not open codec (../../../../../../../csrc/com/xuggle/xuggler/StreamCoder.cpp:831)
Exception in thread "main" java.lang.RuntimeException: could not open stream com.xuggle.xuggler.IStream@-1921013728[index:1;id:0;streamcoder:com.xuggle.xuggler.IStreamCoder@-1921010088[codec=com.xuggle.xuggler.ICodec@-1921010232[type=CODEC_TYPE_AUDIO;id=CODEC_ID_VORBIS;name=libvorbis;];time base=1/44100;frame rate=0/0;sample rate=44100;channels=1;];framerate:0/0;timebase:1/90000;direction:OUTBOUND;]: Operation not permitted
    at com.xuggle.mediatool.MediaWriter.openStream(MediaWriter.java:1192)
    at com.xuggle.mediatool.MediaWriter.getStream(MediaWriter.java:1052)
    at com.xuggle.mediatool.MediaWriter.encodeAudio(MediaWriter.java:830)
    at com.xuggle.mediatool.MediaWriter.onAudioSamples(MediaWriter.java:1441)
    at com.xuggle.mediatool.AMediaToolMixin.onAudioSamples(AMediaToolMixin.java:89)
    at com.xuggle.mediatool.MediaReader.dispatchAudioSamples(MediaReader.java:628)
    at com.xuggle.mediatool.MediaReader.decodeAudio(MediaReader.java:555)
    at com.xuggle.mediatool.MediaReader.readPacket(MediaReader.java:469)
    at com.mycompany.xugglertest.App.main(App.java:13)
Java Result: 1

何か案は?

4

1 に答える 1

3

Xugglerでは、常にサンプル レートを設定できるとは限らないという奇妙なことが起こっていますIAudioSamples。を使用する必要がありますIAudioResampler

これを理解するのにしばらく時間がかかりました。Marty によるこの投稿は大いに役立ちましたが、彼のコードは現在古くなっています。

修正方法は次のとおりです。

.

エンコード前

ここでは、オーディオ入力が適切に設定されていると想定しており、その結果、 がIStreamCoder呼び出されaudioCoderます。

それが完了したら、おそらく次のIMediaWriterようにオーディオ ストリームを開始して追加します。

final IMediaWriter oggWriter = ToolFactory.makeWriter(oggOutputFile);

// Using stream 1 'cause there is also a video stream.
// For an audio only file you should use stream 0.
oggWriter.addAudioStream(1, 1, ICodec.ID.CODEC_ID_VORBIS, 
                         audioCoder.getChannels(), audioCoder.getSampleRate());

を作成しますIAudioResampler

IAudioResampler oggResampler = IAudioResampler.make(audioCoder.getChannels(), 
                                                   audioCoder.getChannels(), 
                                                   audioCoder.getSampleRate(),
                                                   audioCoder.getSampleRate(),  
                                                   IAudioSamples.Format.FMT_FLT, 
                                                   audioCoder.getSampleFormat());

そしてIMediaWriter、そのサンプル形式に更新するように伝えます:

// The stream 1 here is consistent with the stream we added earlier.
oggWriter.getContainer().getStream(1).getStreamCoder().
                         setSampleFormat(IAudioSamples.Format.FMT_FLT);

.

エンコード中

現在、次のように を開始しIAudioSamplesて、オーディオ データを入力している可能性があります。

IAudioSamples audioSample = IAudioSamples.make(512, audioCoder.getChannels(), 
                                                    audioCoder.getSampleFormat());

int bytesDecoded = audioCoder.decodeAudio(audioSample, packet, offset);

次に、リサンプリングされたデータのIAudioSamplesを開始します。

IAudioSamples vorbisSample = IAudioSamples.make(512, audioCoder.getChannels(),
                                                IAudioSamples.Format.FMT_FLT);

最後に、オーディオ データをリサンプリングし、結果を書き込みます。

oggResampler.resample(vorbisSample, audioSample, 0);

oggWriter.encodeAudio(1, vorbisSample);  

.

最終的な考え

出力ファイルを適切に再生するためのヒント:

  • 同じコンテナ内でオーディオとビデオを使用する場合、オーディオとビデオのデータ パケットは、各データ パケットのタイムスタンプが前のデータ パケットのタイムスタンプよりも高くなるような順序で書き込まれる必要があります。したがって、ほぼ確実に、オーディオとビデオの書き込みを交互に行う何らかのバッファリング メカニズムが必要になります。
于 2014-05-07T05:06:46.707 に答える