1

Play フレームワークを使用して Java アプリケーションを作成しており、HTTP ライブ ストリーミングが必要です。オンデマンドでオンザフライで mp4 ファイルをセグメント化するつもりです。そのために c-segmenter (Carson McDonald 製) を試しましたが、非常に高速です。ただし、コードを Java アプリケーションに統合して制御を容易にしたいので、Xuggler を試してみました。

ただし、このセットアップでは、実行にかなりの時間がかかるため、Xuggler はオブジェクトをデコードして再コード化しているようです (MacbookPro では 24 秒で実行され、約 12 秒で実行されます)。ファイルをセグメントに分割するためだけに、重労働をせずに同様のコードを実行する方法はありますか?

これは、以下のテスト コードのようなコードでは非常に単純ですが、

public static void segmentMediaFile (String sourceUrl) {
    Logger.debug("Starting segmenting process...");
    IMediaReader mediaReader = ToolFactory.makeReader(sourceUrl);

    MediaSegmenterListener listener = new MediaSegmenterListener();

    IMediaReader reader = ToolFactory.makeReader(sourceUrl);

    reader.addListener(listener);
    int count = 0;

    IMediaWriter currentWriter = makeMediaWriterFromCounter(++count, reader);
    reader.addListener(currentWriter);

    while (reader.readPacket() == null)
      do {
        if (listener.newFile()) {
           reader.removeListener(currentWriter);
           currentWriter.flush();
           currentWriter.close();
           currentWriter = makeMediaWriterFromCounter(++count, reader);
           reader.addListener(currentWriter);
        }
      } while(false);
}

private static IMediaWriter makeMediaWriterFromCounter (final int counter, IMediaReader reader) {
    String destinationUrl = "./public/testdata/test-movie/";
    return ToolFactory.makeWriter(destinationUrl + counter + "_some_name.mov", reader);
}

(リスナーは現在、タイムスタンプに従って新しいファイルを作成する決定を下すだけです)

それとも、これは間違った方法ですか?

4

2 に答える 2

0

私は IPacket に基づいてコードを書きました。algo は openOutput コンテナーのようなもので、ビデオとオーディオのストリームを設定し、入力コンテナーからパケットを読み取り、outputContainer に書き込みます。コードは例外なく正常に動作していますが、音声が正常に動作している代わりに画像を見ることができません。あなたの ID を教えてください。コードをお送りします。何が問題なのかわかるかもしれません。

ありがとう

于 2011-12-23T05:54:54.063 に答える
0

メディア ファイルをセグメント化する次のコードを開発しました。ただし、エンコードも必要だったので、

私はそれをテストしたことはありません(エンコーディングが機能するバージョンはまだありません)が、外部からは正しいと思われるファイルを出力します。たぶん、それは途中で誰かを助けるでしょう。(反抗的に出力.m3u8ファイルを信頼しません)

public static void segmentMediaFile (String sourceFile, String destinationDir, String extension) throws Exception {
    final int segmentSize = 10;
    int counter = 0;

    final IContainer input = IContainer.make();

    // open the input file
    if(!(new File(sourceFile).exists())) throw new Exception("Source file " + sourceFile + " does not exist!");
    input.open(sourceFile, IContainer.Type.READ,null);

    IContainer output = getOutputContainer(counter, input, destinationDir, extension);

    double lastNewFilePostion = 0;
    double currentFilePostion = 0;

    FileWriter fstream = new FileWriter(destinationDir + "prog_index.m3u8");
    BufferedWriter out = new BufferedWriter(fstream);
    out.write( "#EXTM3U\n#EXT-X-TARGETDURATION:10\n#EXT-X-MEDIA-SEQUENCE:0\n");
    out.close();

    for(;;)
    {
      final IPacket pkt = IPacket.make();
      if (input.readNextPacket(pkt) < 0)
            break;

      // Only needed to calculate the last segment size!
      currentFilePostion = pkt.getTimeStamp() * pkt.getTimeBase().getValue();

      if (((currentFilePostion - lastNewFilePostion) >= segmentSize) ||
              (pkt.isKeyPacket() && ((currentFilePostion - lastNewFilePostion) >= segmentSize - 0.5))){
           if(!((currentFilePostion - lastNewFilePostion) >= segmentSize)) Logger.debug("Keyframe overrulled segment at " + currentFilePostion);

           File filename = new File(output.getURL());
           int lastSegementLength = (int) (currentFilePostion - lastNewFilePostion);
           writeTrailer(output);

           fstream = new FileWriter(destinationDir + "prog_index.m3u8",true);
           out = new BufferedWriter(fstream);
           out.write("#EXTINF:" + lastSegementLength + ",\n" + filename.getName() + "\n");
           out.close();

           counter++;
           output = getOutputContainer(counter, input, destinationDir, extension);

           lastNewFilePostion = currentFilePostion;
      }

      output.writePacket(pkt, false);
    }

    // Write the m3u8 file
    File filename = new File(output.getURL());
    int lastSegementLength = (int) (currentFilePostion - lastNewFilePostion);
    String segmentList = "#EXTINF:" + lastSegementLength + ",\n" + filename.getName() + "\n";
    segmentList = segmentList + "#EXT-X-ENDLIST\n";

    fstream = new FileWriter(destinationDir + "prog_index.m3u8",true);
    out = new BufferedWriter(fstream);
    out.write(segmentList);
    out.close();

    writeTrailer(output);
}


private static IContainer getOutputContainer (final int counter, IContainer input, String destinationDir, String extension) throws Exception {
    IContainer output = IContainer.make();
    output.open(destinationDir + "segment_" + counter + "." + extension, IContainer.Type.WRITE, null);

    int numStreams = input.getNumStreams();
    for(int i = 0; i < numStreams; i++)
    {
      final IStream stream = input.getStream(i);
      final IStreamCoder coder = stream.getStreamCoder();
      coder.open();

      IStreamCoder newCoder = IStreamCoder.make(IStreamCoder.Direction.ENCODING, coder);
        if(newCoder != null ){
          output.addNewStream(i);
          output.getStream(i).setStreamCoder(newCoder);
          newCoder.open();
      } else {
          Logger.warn("Is there an invalid stream present in video file: " + input.getURL() + "! IGNORING, but this might be serious");
      }


    }

    // write the output header
    writeHeader(output);

    return output;
}

private static void writeHeader(IContainer output){
    output.writeHeader();
}

private static void writeTrailer(IContainer output){
    // write the output trailers
    output.writeTrailer();
    int streams = output.getNumStreams();
    for(int j = 0; j < streams; j++)
    {
      output.getStream(j).getStreamCoder().close();
    }
    output.close();
}
于 2012-01-05T20:25:45.670 に答える