我使用mp4parser来附加录制的音频。当我点击暂停或停止按钮时,我收到以下nullpointer异常错误。我希望文件存储在缓存中的外部目录中。不能理解我犯错的地方。
07-22 13:21:18.847: I/RecordActivity(2478):
/data/data/com.example.audiorecordertest/cache/tmprecord
07-22 13:21:24.751: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.755: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.755: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.761: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.761: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.762: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.767: D/isoparser(2478): AbstractBox:mem mapping tkhd
07-22 13:21:24.767: D/isoparser(2478): AbstractBox:parsing details of tkhd
07-22 13:21:24.768: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.768: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.769: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.770: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.770: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.772: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.773: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.773: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.774: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.775: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.775: D/isoparser(2478): AbstractBox:mem mapping hdlr
07-22 13:21:24.775: D/isoparser(2478): AbstractBox:parsing details of hdlr
07-22 13:21:24.776: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.777: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.778: D/isoparser(2478): AbstractBox:mem mapping stts
07-22 13:21:24.778: D/isoparser(2478): AbstractBox:parsing details of stts
07-22 13:21:24.779: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.780: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.780: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.781: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.782: D/isoparser(2478): AbstractBox:mem mapping mdhd
07-22 13:21:24.782: D/isoparser(2478): AbstractBox:parsing details of mdhd
07-22 13:21:24.782: D/isoparser(2478): AbstractBox:mem mapping mvhd
07-22 13:21:24.782: D/isoparser(2478): AbstractBox:parsing details of mvhd
07-22 13:21:24.799: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.799: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.800: D/isoparser(2478): AbstractContainerBox:Parsing next() box
07-22 13:21:24.801: W/System.err(2478): java.lang.NullPointerException
07-22 13:21:24.803: W/System.err(2478): at com.googlecode.mp4parser.authoring.
container.mp4.MovieCreator.build(MovieCreator.java:48)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
Mp4ParserWrapper.append(Mp4ParserWrapper.java:72)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
Mp4ParserWrapper.append(Mp4ParserWrapper.java:34)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
RecordActivity.appendToFile(RecordActivity.java:179)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
RecordActivity.access$7(RecordActivity.java:178)
07-22 13:21:24.803: W/System.err(2478): at com.example.audiorecordertest.
RecordActivity$2.onClick(RecordActivity.java:108)
07-22 13:21:24.804: W/System.err(2478): at
android.view.View.performClick(View.java:4456)
07-22 13:21:24.804: W/System.err(2478): at
android.view.View$PerformClick.run(View.java:18465)
07-22 13:21:24.805: W/System.err(2478): at
android.os.Handler.handleCallback(Handler.java:733)
07-22 13:21:24.805: W/System.err(2478): at
android.os.Handler.dispatchMessage(Handler.java:95)
07-22 13:21:24.805: W/System.err(2478): at android.os.Looper.loop(Looper.java:136)
07-22 13:21:24.805: W/System.err(2478): at
android.app.ActivityThread.main(ActivityThread.java:5086)
07-22 13:21:24.806: W/System.err(2478): at
java.lang.reflect.Method.invokeNative(Native Method)
07-22 13:21:24.806: W/System.err(2478): at
java.lang.reflect.Method.invoke(Method.java:515)
07-22 13:21:24.807: W/System.err(2478): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
07-22 13:21:24.807: W/System.err(2478): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-22 13:21:24.808: W/System.err(2478): at
dalvik.system.NativeStart.main(Native Method)
这是我的代码:
RecordActivity
import java.io.File;
import java.io.IOException;
import android.support.v7.app.ActionBarActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
public class RecordActivity extends ActionBarActivity {
protected static final String TAG = "RecordActivity";
private ImageButton start_btn,pause_btn,stop_btn;
private MediaRecorder myrecorder = null;
Context mcontext;
private String outputFile;
private String mTargetRecordFileName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_record);
mcontext = this;
start_btn = (ImageButton) findViewById(R.id.im_start_btn);
pause_btn = (ImageButton) findViewById(R.id.im_pause_btn);
stop_btn = (ImageButton) findViewById(R.id.im_stop_btn);
stop_btn.setVisibility(View.INVISIBLE);
pause_btn.setVisibility(View.INVISIBLE);
start_btn.setEnabled(true);
mTargetRecordFileName = getOutputFile();
start_btn.setOnClickListener(new OnClickListener() {
@SuppressLint("InlinedApi")
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
start_btn.setVisibility(View.INVISIBLE);
pause_btn.setVisibility(View.VISIBLE);
stop_btn.setVisibility(View.VISIBLE);
start_btn.setEnabled(false);
pause_btn.setEnabled(true);
myrecorder = new MediaRecorder();
myrecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myrecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
myrecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myrecorder.setOutputFile(getTemporaryFileName());
start(v);
}
private void start(View v) {
// TODO Auto-generated method stub
try{
myrecorder.prepare();
myrecorder.start();
Log.i(TAG, getTemporaryFileName());
} catch(IllegalStateException e){
} catch(IOException e){
}
}
});
pause_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
appendToFile(mTargetRecordFileName, getTemporaryFileName());
myrecorder.stop();
myrecorder.reset();
myrecorder.release();
pause_btn.setVisibility(View.INVISIBLE);
start_btn.setVisibility(View.VISIBLE);
stop_btn.setVisibility(View.VISIBLE);
start_btn.setEnabled(true);
stop_btn.setEnabled(true);
}
});
stop_btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
myrecorder.stop(); // stop recording
myrecorder.reset(); // set state to idle
myrecorder.release(); // release resources back to the system
myrecorder = null;
appendToFile(mTargetRecordFileName, getTemporaryFileName());
start_btn.setVisibility(View.VISIBLE);
pause_btn.setVisibility(View.INVISIBLE);
start_btn.setEnabled(true);
}
});
}
private String getOutputFile()
{
String path = Environment.getExternalStorageDirectory().
getAbsolutePath() + "/MyFolder/";
File dir = new File(path);
if(!dir.exists())
dir.mkdirs();
outputFile = path + File.separator + "MA_"+"Srijith".subSequence(0, 3);
return outputFile;
}
private String getTemporaryFileName() {
return mcontext.getCacheDir().getAbsolutePath() + File.separator + "tmprecord";
}
private void appendToFile(final String targetFileName,final String newFileName) {
Mp4ParserWrapper.append(targetFileName, newFileName);
}
@Override
protected void onDestroy() {
super.onDestroy();
try {
trimCache(getApplicationContext());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void trimCache(Context context) {
try {
File dire = context.getCacheDir();
if (dire != null && dire.isDirectory()) {
//deleteDir(dire);
deleteDir(dire);
}
} catch (Exception e) {
// TODO: handle exception
}
}
private static boolean deleteDir(File dire) {
// TODO Auto-generated method stub
if (dire != null && dire.isDirectory()) {
String[] children = dire.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dire, children[i]));
if (!success) {
return false;
}
}
}
return dire.delete();
}
}
Mp4ParserWrapper
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import java.util.List;
import android.util.Log;
import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.FileDataSourceImpl;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.googlecode.mp4parser.authoring.tracks.AppendTrack;
public class Mp4ParserWrapper {
public static final int FILE_BUFFER_SIZE = 1024;
private static final String TAG = "Mp4ParserWrapper";
public static boolean append(String mainFileName, String anotherFileName){
boolean rvalue = false;
try{
File targetFile = new File(mainFileName);
File anotherFile = new File(anotherFileName);
if (targetFile.exists() && targetFile.length() > 0) {
String tmpFileName = mainFileName + ".tmp";
append(mainFileName, anotherFileName, tmpFileName);
copyFile(tmpFileName, mainFileName);
rvalue = anotherFile.delete() && new File(tmpFileName).delete();
} else if (targetFile.createNewFile()) {
copyFile(anotherFileName, mainFileName);
rvalue = anotherFile.delete();
}
} catch (IOException e) {
Log.e(TAG,"Append two mp4 files exception", e);
} catch(NullPointerException ex){
ex.printStackTrace();
}
return rvalue;
}
public static void copyFile(final String from, final String destination)
throws IOException {
FileInputStream in = new FileInputStream(from);
FileOutputStream out = new FileOutputStream(destination);
copy(in, out);
in.close();
out.close();
}
public static void copy(FileInputStream in, FileOutputStream out) throws IOException {
byte[] buf = new byte[FILE_BUFFER_SIZE];
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
}
public static void append(
final String firstFile,
final String secondFile,
final String newFile) throws IOException {
final Movie movieA = MovieCreator.build(new FileDataSourceImpl(secondFile));
final Movie movieB = MovieCreator.build(new FileDataSourceImpl(firstFile));
final Movie finalMovie = new Movie();
final List<Track> movieOneTracks = movieA.getTracks();
final List<Track> movieTwoTracks = movieB.getTracks();
for (int i = 0; i < movieOneTracks.size() || i < movieTwoTracks.size(); ++i) {
finalMovie.addTrack(new
AppendTrack(movieTwoTracks.get(i), movieOneTracks.get(i)));
}
final Container container = new DefaultMp4Builder().build(finalMovie);
final FileOutputStream fos = new FileOutputStream(new File(String.format(newFile)));
final WritableByteChannel bb = Channels.newChannel(fos);
container.writeContainer(bb);
fos.close();
}
}
请帮忙。
答案 0 :(得分:0)
检查以下两行:
final Movie movieA = MovieCreator.build(new FileDataSourceImpl(secondFile));
final Movie movieB = MovieCreator.build(new FileDataSourceImpl(firstFile));
没有行号,因此我无法看到Mp4ParserWrapper
类中哪一行是第72行,但是出现错误的地方。如果我理解正确,则变量secondFile
已通过getTemporaryFileName()
初始化,这看起来非常可疑。难道它不是指向一些电影文件吗?
---根据您的评论进行编辑:
我从未与MovieCreator
合作过,但却找不到相关信息,但我猜你是以错误的方式使用append
功能。
public static void append(
final String firstFile,
final String secondFile,
final String newFile)
您宣传firstFile
和secondFile
作为输出。但如果我理解正确,这些实际上应该是输入文件。因此,您应该将firstFile
指向一个mp4文件,将secondFile
指向另一个mp4文件。 append
函数将这两个文件的轨道连接成一个文件。在newFile
中,您应该指定要保存此结果新文件的路径。