Я разработал следующий код для сегментации медиа-файлов.Однако, поскольку мне также требовалось кодирование,
Я никогда не проверял его (и у меня еще нет версии с кодировкой), но он выдает файлы, которые кажутся правильными извне.Может быть, это поможет кому-то в пути.(демонстративно не будет доверять выходному файлу .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();
}