parent
7411d55855
commit
aa88eb08c6
@ -0,0 +1,35 @@ |
|||||||
|
package com.otaliastudios.cameraview; |
||||||
|
|
||||||
|
|
||||||
|
import android.location.Location; |
||||||
|
import android.support.test.filters.SmallTest; |
||||||
|
import android.support.test.runner.AndroidJUnit4; |
||||||
|
|
||||||
|
import org.junit.Test; |
||||||
|
import org.junit.runner.RunWith; |
||||||
|
import org.mockito.Mockito; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals; |
||||||
|
import static org.junit.Assert.assertNull; |
||||||
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class) |
||||||
|
@SmallTest |
||||||
|
public class VideoRecorderTest extends BaseTest { |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testRecorder() { |
||||||
|
VideoResult result = new VideoResult(); |
||||||
|
VideoRecorder.VideoResultListener listener = Mockito.mock(VideoRecorder.VideoResultListener.class); |
||||||
|
VideoRecorder recorder = new VideoRecorder(result, listener) { |
||||||
|
void start() {} |
||||||
|
}; |
||||||
|
recorder.start(); |
||||||
|
recorder.stop(); |
||||||
|
Mockito.verify(listener, Mockito.times(1)).onVideoResult(result); |
||||||
|
assertNull(recorder.mListener); |
||||||
|
assertNull(recorder.mResult); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,93 @@ |
|||||||
|
package com.otaliastudios.cameraview; |
||||||
|
|
||||||
|
import android.hardware.Camera; |
||||||
|
import android.media.CamcorderProfile; |
||||||
|
import android.media.MediaRecorder; |
||||||
|
|
||||||
|
/** |
||||||
|
* A {@link VideoRecorder} that uses {@link android.media.MediaRecorder} APIs. |
||||||
|
*/ |
||||||
|
class MediaRecorderVideoRecorder extends VideoRecorder { |
||||||
|
|
||||||
|
private static final String TAG = MediaRecorderVideoRecorder.class.getSimpleName(); |
||||||
|
private static final CameraLogger LOG = CameraLogger.create(TAG); |
||||||
|
|
||||||
|
private MediaRecorder mMediaRecorder; |
||||||
|
private CamcorderProfile mProfile; |
||||||
|
|
||||||
|
MediaRecorderVideoRecorder(VideoResult stub, VideoResultListener listener, Camera camera, int cameraId) { |
||||||
|
super(stub, listener); |
||||||
|
mMediaRecorder = new MediaRecorder(); |
||||||
|
mMediaRecorder.setCamera(camera); |
||||||
|
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); |
||||||
|
mProfile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_HIGH); |
||||||
|
// TODO: should get a profile of a quality compatible with the chosen size.
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
void start() { |
||||||
|
if (mResult.getAudio() == Audio.ON) { |
||||||
|
// Must be called before setOutputFormat.
|
||||||
|
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); |
||||||
|
} |
||||||
|
|
||||||
|
Size size = mResult.getRotation() % 180 != 0 ? mResult.getSize().flip() : mResult.getSize(); |
||||||
|
mMediaRecorder.setOutputFormat(mProfile.fileFormat); |
||||||
|
mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); |
||||||
|
mMediaRecorder.setVideoSize(size.getWidth(), size.getHeight()); |
||||||
|
mMediaRecorder.setVideoEncoder(new Mapper1().map(mResult.getCodec())); |
||||||
|
mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate); |
||||||
|
if (mResult.getAudio() == Audio.ON) { |
||||||
|
mMediaRecorder.setAudioChannels(mProfile.audioChannels); |
||||||
|
mMediaRecorder.setAudioSamplingRate(mProfile.audioSampleRate); |
||||||
|
mMediaRecorder.setAudioEncoder(mProfile.audioCodec); |
||||||
|
mMediaRecorder.setAudioEncodingBitRate(mProfile.audioBitRate); |
||||||
|
} |
||||||
|
if (mResult.getLocation() != null) { |
||||||
|
mMediaRecorder.setLocation( |
||||||
|
(float) mResult.getLocation().getLatitude(), |
||||||
|
(float) mResult.getLocation().getLongitude()); |
||||||
|
} |
||||||
|
mMediaRecorder.setOutputFile(mResult.getFile().getAbsolutePath()); |
||||||
|
mMediaRecorder.setOrientationHint(mResult.getRotation()); |
||||||
|
mMediaRecorder.setMaxFileSize(mResult.getMaxSize()); |
||||||
|
mMediaRecorder.setMaxDuration(mResult.getMaxDuration()); |
||||||
|
mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() { |
||||||
|
@Override |
||||||
|
public void onInfo(MediaRecorder mediaRecorder, int what, int extra) { |
||||||
|
switch (what) { |
||||||
|
case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED: |
||||||
|
case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED: |
||||||
|
stop(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
// Not needed. mMediaRecorder.setPreviewDisplay(mPreview.getSurface());
|
||||||
|
|
||||||
|
try { |
||||||
|
mMediaRecorder.prepare(); |
||||||
|
mMediaRecorder.start(); |
||||||
|
} catch (Exception e) { |
||||||
|
mResult = null; |
||||||
|
stop(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
void stop() { |
||||||
|
if (mMediaRecorder != null) { |
||||||
|
try { |
||||||
|
mMediaRecorder.stop(); |
||||||
|
} catch (Exception e) { |
||||||
|
// This can happen if stopVideo() is called right after takeVideo(). We don't care.
|
||||||
|
LOG.w("stop:", "Error while closing media recorder. Swallowing", e); |
||||||
|
} |
||||||
|
mMediaRecorder.release(); |
||||||
|
} |
||||||
|
|
||||||
|
super.stop(); |
||||||
|
mProfile = null; |
||||||
|
mMediaRecorder = null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
package com.otaliastudios.cameraview; |
||||||
|
|
||||||
|
import android.support.annotation.Nullable; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
|
||||||
|
/** |
||||||
|
* Interface for video recording. |
||||||
|
* Don't call start if already started. Don't call stop if already stopped. |
||||||
|
* Don't reuse. |
||||||
|
*/ |
||||||
|
abstract class VideoRecorder { |
||||||
|
|
||||||
|
/* tests */ VideoResult mResult; |
||||||
|
/* tests */ VideoResultListener mListener; |
||||||
|
|
||||||
|
VideoRecorder(VideoResult stub, VideoResultListener listener) { |
||||||
|
mResult = stub; |
||||||
|
mListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
abstract void start(); |
||||||
|
|
||||||
|
void stop() { |
||||||
|
mListener.onVideoResult(mResult); |
||||||
|
mListener = null; |
||||||
|
mResult = null; |
||||||
|
} |
||||||
|
|
||||||
|
interface VideoResultListener { |
||||||
|
void onVideoResult(@Nullable VideoResult result); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue