我正在使用com.googlecode.mp4parser
库合并音频文件。我有一个外部音频mp3文件,该文件存储在raw
资源中。由于以下异常,此文件无法合并,以下是我的代码:
从原始文件夹读取文件:
InputStream is = context.getResources().openRawResource(R.raw.my_mp3_file);
OutputStream output = null;
try {
File file = new File(context.getFilesDir(), "silence.mp3");
if(!file.exists()) {
file.createNewFile();
}
output = new FileOutputStream(file);
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = is.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
output.close();
fileReference= file;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace(); // handle exception, define IOException and others
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
读取电影的代码(失败):
if(fileReference.exists()) {
Movie m = new MovieCreator().build(fileReference.getAbsolutePath());
}
在获取此
Movie m
时,我的代码未能引发异常:java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.coremedia.iso.boxes.MovieBox.getBoxes(java.lang.Class)' on a null object reference
它适用于某些mp3文件,而原始资源文件失败了吗?怎么了
最佳答案
经过大量研究,这是我的结论和解决方案
用于合并音频和视频的MP4Parser仅使用.m4a扩展名
String root = Environment.getExternalStorageDirectory().toString();
String audio = root + "/" + "tests.m4a";
String video = root + "/" + "output.mp4";
String output = root + "/" + "aud_vid.mp4";
mux(video, audio, output);
这是方法
public boolean mux(String videoFile, String audioFile, String outputFile) {
Movie video;
try {
video = new MovieCreator().build(videoFile);
} catch (RuntimeException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
Movie audio;
try {
audio = new MovieCreator().build(audioFile);
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (NullPointerException e) {
e.printStackTrace();
return false;
}
Track audioTrack = audio.getTracks().get(0);
video.addTrack(audioTrack);
Container out = new DefaultMp4Builder().build(video);
FileOutputStream fos;
try {
fos = new FileOutputStream(outputFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
BufferedWritableFileByteChannel byteBufferByteChannel = new BufferedWritableFileByteChannel(fos);
try {
out.writeContainer(byteBufferByteChannel);
byteBufferByteChannel.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
private static class BufferedWritableFileByteChannel implements WritableByteChannel {
private static final int BUFFER_CAPACITY = 1000000;
private boolean isOpen = true;
private final OutputStream outputStream;
private final ByteBuffer byteBuffer;
private final byte[] rawBuffer = new byte[BUFFER_CAPACITY];
private BufferedWritableFileByteChannel(OutputStream outputStream) {
this.outputStream = outputStream;
this.byteBuffer = ByteBuffer.wrap(rawBuffer);
}
@Override
public int write(ByteBuffer inputBuffer) throws IOException {
int inputBytes = inputBuffer.remaining();
if (inputBytes > byteBuffer.remaining()) {
dumpToFile();
byteBuffer.clear();
if (inputBytes > byteBuffer.remaining()) {
throw new BufferOverflowException();
}
}
byteBuffer.put(inputBuffer);
return inputBytes;
}
@Override
public boolean isOpen() {
return isOpen;
}
@Override
public void close() throws IOException {
dumpToFile();
isOpen = false;
}
private void dumpToFile() {
try {
outputStream.write(rawBuffer, 0, byteBuffer.position());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}