这是我的代码:
RecordActivity.java
public class RecordActivity extends ActionBarActivity {
protected static final String TAG = "RecordActivity";
private ImageButton start_btn,pause_btn,stop_btn;
private MediaRecorder myrecorder = null;
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
Context mcontext;
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);
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
appendToFile(mTargetRecordFileName, getTemporaryFileName());
myrecorder.stop(); // stop recording
myrecorder.reset(); // set state to idle
myrecorder.release(); // release resources back to the system
myrecorder = null;
start_btn.setVisibility(View.VISIBLE);
pause_btn.setVisibility(View.INVISIBLE);
start_btn.setEnabled(true);
}
});
}
private String getTemporaryFileName() {
return mcontext.getCacheDir().getAbsolutePath() + File.separator + "tmprecord";
}
private void appendToFile(final String targetFileName,final String newFileName) {
Mp4ParserWrapper.append(targetFileName, newFileName);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.record, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Mp4ParserWrapper.java
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);
}
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();
}
}
我正在使用 isoparser1.0 RC-27.jar 来合并音频文件。但是我收到了以下错误:
07-21 14:02:15.230: I/RecordActivity(8748): /data/data/com.example.audiorecordertest/cache/tmprecord
07-21 14:02:19.433: D/AndroidRuntime(8748): Shutting down VM
07-21 14:02:19.433: W/dalvikvm(8748): threadid=1: thread exiting with uncaught exception (group=0x41635d40)
07-21 14:02:19.437: E/AndroidRuntime(8748): FATAL EXCEPTION: main
07-21 14:02:19.437: E/AndroidRuntime(8748): Process: com.example.audiorecordertest, PID: 8748
07-21 14:02:19.437: E/AndroidRuntime(8748): java.lang.NullPointerException
07-21 14:02:19.437: E/AndroidRuntime(8748): at java.io.File.fixSlashes(File.java:185)
07-21 14:02:19.437: E/AndroidRuntime(8748): at java.io.File.<init>(File.java:134)
07-21 14:02:19.437: E/AndroidRuntime(8748): at com.example.audiorecordertest.Mp4ParserWrapper.append(Mp4ParserWrapper.java:37)
07-21 14:02:19.437: E/AndroidRuntime(8748): at com.example.audiorecordertest.RecordActivity.appendToFile(RecordActivity.java:195)
07-21 14:02:19.437: E/AndroidRuntime(8748): at com.example.audiorecordertest.RecordActivity.access$7(RecordActivity.java:194)
07-21 14:02:19.437: E/AndroidRuntime(8748): at com.example.audiorecordertest.RecordActivity$2.onClick(RecordActivity.java:98)
07-21 14:02:19.437: E/AndroidRuntime(8748): at android.view.View.performClick(View.java:4456)
07-21 14:02:19.437: E/AndroidRuntime(8748): at android.view.View$PerformClick.run(View.java:18465)
07-21 14:02:19.437: E/AndroidRuntime(8748): at android.os.Handler.handleCallback(Handler.java:733)
07-21 14:02:19.437: E/AndroidRuntime(8748): at android.os.Handler.dispatchMessage(Handler.java:95)
07-21 14:02:19.437: E/AndroidRuntime(8748): at android.os.Looper.loop(Looper.java:136)
07-21 14:02:19.437: E/AndroidRuntime(8748): at android.app.ActivityThread.main(ActivityThread.java:5086)
07-21 14:02:19.437: E/AndroidRuntime(8748): at java.lang.reflect.Method.invokeNative(Native Method)
07-21 14:02:19.437: E/AndroidRuntime(8748): at java.lang.reflect.Method.invoke(Method.java:515)
07-21 14:02:19.437: E/AndroidRuntime(8748): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
07-21 14:02:19.437: E/AndroidRuntime(8748): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-21 14:02:19.437: E/AndroidRuntime(8748): at dalvik.system.NativeStart.main(Native Method)
最好知道我使用的容器是什么以及如何将音频文件从容器移动到SD卡。
答案 0 :(得分:0)
以下行导致问题:
appendToFile(mTargetRecordFileName, getTemporaryFileName());
您已声明mTargetRecordFileName
,但未在任何地方初始化,因此它正在尝试使用null
文件名执行文件操作。
以下方法将返回您可以分配给mTargetRecordFileName
的根外部存储中的文件的文件名:
private String getOutputFile()
{
return Environment.getExternalStorageDirectory() +
File.separator + "media_file_name.mp4";
}
另外,请确保您在清单中获得以下权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />