Encoding 使用Xuggler快速分割文件,无需解码/编码

Encoding 使用Xuggler快速分割文件,无需解码/编码,encoding,playframework,http-live-streaming,xuggle,Encoding,Playframework,Http Live Streaming,Xuggle,使用Play框架编写Java应用程序,需要一些HTTP实时流。我打算按需动态分割mp4文件。我试过一个c-切割器(来自Carson McDonald),速度非常快。然而,我喜欢将代码集成到我的Java应用程序中,以便于控制,所以Xugler尝试了 然而,在这个设置中,Xugler似乎对对象进行解码和重新编码,因为运行它需要相当长的时间(在MacbookPro上运行24秒大约需要12秒)。有没有一种方法可以运行类似的代码,而不需要执行任何繁重的工作,只需将文件分段 虽然这对于下面的测试代码非常简单

使用Play框架编写Java应用程序,需要一些HTTP实时流。我打算按需动态分割mp4文件。我试过一个c-切割器(来自Carson McDonald),速度非常快。然而,我喜欢将代码集成到我的Java应用程序中,以便于控制,所以Xugler尝试了

然而,在这个设置中,Xugler似乎对对象进行解码和重新编码,因为运行它需要相当长的时间(在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);
}
(侦听器当前只是根据时间戳决定创建一个新文件)


或者这是一种错误的方法吗?

我基于IPacket编写了代码,algo是这样的 openOutput容器设置视频和音频流,然后从输入容器读取数据包并写入outputContainer。 代码工作正常,没有任何异常等,但唯一的问题是我无法看到图片,而音频工作正常。 让我知道你的身份证,我会把代码发给你,也许你会发现其中的错误


谢谢

我开发了以下代码来分割媒体文件。但是,由于我也需要编码

我从来没有测试过它(而且,编码的版本还没有工作),但它会输出从外部看似乎正确的文件。也许它会在路上帮助别人。(公然不信任output.m3u8文件)

public static void segmentMediaFile(字符串sourceFile、字符串destinationDir、字符串扩展名)引发异常{
最终整数段大小=10;
int计数器=0;
最终IContainer输入=IContainer.make();
//打开输入文件
如果(!(新文件(sourceFile).exists())抛出新异常(“源文件”+sourceFile+“不存在!”);
open(sourceFile,IContainer.Type.READ,null);
IContainer输出=getOutputContainer(计数器、输入、目标DIR、扩展名);
double lastNewFilePostion=0;
双CurrentFilePosition=0;
FileWriter fstream=新的FileWriter(destinationDir+“prog_index.m3u8”);
BufferedWriter out=新的BufferedWriter(fstream);
out.write(“#EXTM3U\n#EXT-X-TARGETDURATION:10\n#EXT-X-MEDIA-SEQUENCE:0\n”);
out.close();
对于(;;)
{
最终IPacket pkt=IPacket.make();
如果(输入.readNextPacket(pkt)<0)
打破
//只需要计算最后一段的大小!
CurrentFilePosition=pkt.getTimeStamp()*pkt.getTimeBase().getValue();
如果(((CurrentFilePosition-LastNewFilePosition)>=segmentSize)||
(pkt.isKeyPacket()&&((CurrentFilePosition-LastNewFilePosition)>=segmentSize-0.5))){
如果(!((CurrentFilePosition-LastNewFilePosition)>=segmentSize))Logger.debug(“在“+CurrentFilePosition”处的关键帧覆盖段);
文件名=新文件(output.getURL());
int lastSegementLength=(int)(CurrentFilePosition-LastNewFilePosition);
写入跟踪程序(输出);
fstream=newfilewriter(destinationDir+“prog_index.m3u8”,true);
out=新的缓冲写入程序(fstream);
out.write(“#exef:+lastSegementLength+”,\n“+filename.getName()+”\n”);
out.close();
计数器++;
output=getOutputContainer(计数器、输入、目标DIR、扩展名);
LastNewFilePosition=CurrentFilePosition;
}
output.writePacket(pkt,false);
}
//写入m3u8文件
文件名=新文件(output.getURL());
int lastSegementLength=(int)(CurrentFilePosition-LastNewFilePosition);
String segmentList=“#exef:+lastSegementLength+”,\n“+filename.getName()+”\n”;
分段列表=分段列表+“#EXT-X-ENDLIST\n”;
fstream=newfilewriter(destinationDir+“prog_index.m3u8”,true);
out=新的缓冲写入程序(fstream);
写出(段列表);
out.close();
写入跟踪程序(输出);
}
私有静态IContainer getOutputContainer(最终int计数器、IContainer输入、字符串destinationDir、字符串扩展名)引发异常{
IContainer输出=IContainer.make();
output.open(destinationDir+“段\计数器+”+扩展名,IContainer.Type.WRITE,null);
int numStreams=input.getNumStreams();
for(int i=0;i
我自己有一个工作系统,至少对于分段(使用Toolfactory和MediaToolAdapter),我现在正在使用内置分段进行编码。如果你不介意,可以分享你的代码吗?我希望你没有解码视频。我将在未来几天内尝试。已经休假一周了,
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();
}