0

This is my code:

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();

}
}

I am using isoparser1.0 RC-27.jar for merging audio files. But am getting the following errors:

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)

It would be good to know what is the container which i've used and how to move audio files from container to sd card.

Lucifer
  • 29,392
  • 25
  • 90
  • 143
Srijith
  • 1,695
  • 17
  • 29

1 Answers1

0

The following line is causing the problem:

 appendToFile(mTargetRecordFileName, getTemporaryFileName());

You've declared mTargetRecordFileName, but not initialized it anywhere, so it's trying to perform a file operation using a null filename.

The following method will return a filename for a file in the root external storage that you can assign to mTargetRecordFileName:

private String getOutputFile()
{
    return Environment.getExternalStorageDirectory() + 
        File.separator + "media_file_name.mp4";
}

Also, make sure you've got the following permission in the manifest:

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Mike M.
  • 38,532
  • 8
  • 99
  • 95
  • But i am checking for that in my **Mp4ParserWrapper** 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(); } Please excuse me if am wrong. Iam new to android – Srijith Jul 21 '14 at 09:00
  • It looks like you're only catching `IOException`s. This line is throwing a `NullPointerException`: `File targetFile = new File(mainFileName);`. – Mike M. Jul 21 '14 at 09:05
  • Do u have any suggestions on what to be initialized on that string. Iam really stuck here. Any help please. Or any other suggestions on how to append two audio files. – Srijith Jul 21 '14 at 09:41
  • Well, it appears that it's the final output file, so you just need to decide where you want to save it, and with what filename, and you can create a function similar to `getTemporaryFileName()`. If you tell me what version of Android you're testing on, I can update my answer with the function you need. – Mike M. Jul 21 '14 at 09:54
  • I am running on 4.4.2 – Srijith Jul 21 '14 at 10:00
  • As the description says, that file will be in the root directory of external storage, so you'll want to change it after testing to whichever directory your app will be storing files in. – Mike M. Jul 21 '14 at 10:33