11

I've been having some problems while trying to fix a simple video recording app*. I think I followed the sequence of steps correctly. The following is a simplification of the part of the code that is giving me problems. This code is executed only as a callback once a button is pressed:

if ( mRecorder != null){
    mRecorder.reset();
    mRecorder.release();
}
mRecorder = new MediaRecorder();
if(mViewer.hasSurface){
    mRecorder.setPreviewDisplay(mViewer.holder.getSurface());
    Log.d(TAG,"Surface has been set");
}
try {
    Log.d(TAG,"Sleeping for 4000 mili");
    Thread.sleep(4000);
    Log.d(TAG,"Waking up");
} catch (InterruptedException e) {
    Log.e(TAG,"InterruptedException");
    e.printStackTrace();
}
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);  
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setVideoFrameRate(12);
mRecorder.setVideoSize(176, 144);
mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setMaxDuration(MAX_DURATION_TEST);

String targetFile = "/sdcard/webcamera/temp.mp4";
File localFile = new File(targetFile);
if(localFile.exists()){
    Log.d(TAG,"Local file exists");
}else{
    Log.d(TAG,"Local file does not exist");
}
mRecorder.setOutputFile(targetFile);
try {
    mRecorder.prepare();
    bPrepared = true;
    Log.i(TAG,"prepared");
    return;
} catch (IllegalStateException e) {
    e.printStackTrace();            
} catch (IOException e) {
    Log.e(TAG ,"IOException");
    Log.e(TAG,"Message: "+e.getMessage());
    StackTraceElement[] array = e.getStackTrace();
    for(StackTraceElement element : array){
        Log.e(TAG,""+element.toString());
    }
}

The important thing which I don't understand here is that whenever I put the video encoder to be MPEG_4_S it works. On the other hand whenever I put the encoder to be H264 it just does not. The problem is that this piece of code is just part of a bigger project, and the rest of it kind of expects this video to be encoded with h264.

I'm testing on a samsung Galaxy I-7500, running on froyo by the way. And I think the Galaxy I-9000 has the same problem.

The puzzling thing for me is that according to this documentation right here: http://developer.android.com/guide/appendix/media-formats.html, MPEG_4_SP encoding should not be supported at all, while H264 is supported since honeycomb. So why is it working with MPEG_4_SP at all? and is it possible to make it work with H264?

The error I get is not really clear.

07-11 00:01:40.626: ERROR/MediaSource(1386): Message: prepare failed.
07-11 00:01:40.766: ERROR/MediaSource(1386): android.media.MediaRecorder._prepare(Native Method)
07-11 00:01:40.766: ERROR/MediaSource(1386): android.media.MediaRecorder.prepare(MediaRecorder.java:508)
07-11 00:01:40.766: ERROR/MediaSource(1386): com.appdh.webcamera.MediaSource.prepareOutput(MediaSource.java:74)
07-11 00:01:40.766: ERROR/MediaSource(1386): com.appdh.webcamera.MainActivity.startDetectCamera(MainActivity.java:312)

*Actually, the app is a little more complicated than just that, as it also does stream the video over LAN, but the part which I am concerned here has nothing to do with that. You can check this interesing project out here: http://code.google.com/p/ipcamera-for-android/

Bilthon
  • 2,435
  • 8
  • 33
  • 44
  • "Note that any given mobile device may provide support for additional formats or file types not listed in the table." – Stefan H Singer Sep 05 '11 at 15:31
  • 1
    does the device support H.264 recording? You can test it with the default camera on the device or the camera app that comes with android source. You can also try changing the audio encoder format to AAC instead of AMR.. since the document says it can be combined with AAC only (this info is in the link you have provided) – bluefalcon Sep 06 '11 at 12:52

2 Answers2

7

As you already wrote H.264 encoding support can be only expected from devices running honeycomb and later, which currently means only tablets. If you need H.264 you should test for prepare failed and either tell the user that the device is not supported or better block devices without H.264 using market filters. Or you can compile ffmpeg for android - like several other projects do. Have a look at these links:

http://odroid.foros-phpbb.com/t338-ffmpeg-compiled-with-android-ndk

http://bambuser.com/opensource

FFmpeg on Android

Community
  • 1
  • 1
mattlaabs
  • 349
  • 2
  • 12
0

You also can use JCodec

It supports Android and have few samples for it. The best way to compile it with Gradle is:

compile 'com.github.jcodec:jcodec:0.2.0-vg4'

but for latest improvements and bug fixes you need to compile from latest commits (there is still no new release from 2016)

Ruslan Berozov
  • 470
  • 6
  • 14