|
|
@ -6,6 +6,8 @@ import android.media.MediaRecorder; |
|
|
|
import com.otaliastudios.cameraview.CameraLogger; |
|
|
|
import com.otaliastudios.cameraview.CameraLogger; |
|
|
|
import com.otaliastudios.cameraview.VideoResult; |
|
|
|
import com.otaliastudios.cameraview.VideoResult; |
|
|
|
import com.otaliastudios.cameraview.controls.Audio; |
|
|
|
import com.otaliastudios.cameraview.controls.Audio; |
|
|
|
|
|
|
|
import com.otaliastudios.cameraview.controls.VideoCodec; |
|
|
|
|
|
|
|
import com.otaliastudios.cameraview.internal.DeviceEncoders; |
|
|
|
import com.otaliastudios.cameraview.size.Size; |
|
|
|
import com.otaliastudios.cameraview.size.Size; |
|
|
|
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull; |
|
|
|
import androidx.annotation.NonNull; |
|
|
@ -45,49 +47,85 @@ public abstract class FullVideoRecorder extends VideoRecorder { |
|
|
|
|
|
|
|
|
|
|
|
protected boolean onPrepareMediaRecorder(@NonNull VideoResult.Stub stub, @NonNull MediaRecorder mediaRecorder) { |
|
|
|
protected boolean onPrepareMediaRecorder(@NonNull VideoResult.Stub stub, @NonNull MediaRecorder mediaRecorder) { |
|
|
|
mMediaRecorder = mediaRecorder; |
|
|
|
mMediaRecorder = mediaRecorder; |
|
|
|
Size size = stub.rotation % 180 != 0 ? stub.size.flip() : stub.size; |
|
|
|
boolean hasAudio = stub.audio == Audio.ON |
|
|
|
if (stub.audio == Audio.ON || stub.audio == Audio.MONO || stub.audio == Audio.STEREO) { |
|
|
|
|| stub.audio == Audio.MONO |
|
|
|
// Must be called before setOutputFormat.
|
|
|
|
|| stub.audio == Audio.STEREO; |
|
|
|
|
|
|
|
if (hasAudio) { |
|
|
|
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); |
|
|
|
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
mMediaRecorder.setOutputFormat(mProfile.fileFormat); |
|
|
|
mMediaRecorder.setOutputFormat(mProfile.fileFormat); |
|
|
|
if (stub.videoFrameRate <= 0) { |
|
|
|
|
|
|
|
mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); |
|
|
|
// Get the audio mime type
|
|
|
|
stub.videoFrameRate = mProfile.videoFrameRate; |
|
|
|
// https://android.googlesource.com/platform/frameworks/av/+/master/media/libmediaplayerservice/StagefrightRecorder.cpp#1096
|
|
|
|
} else { |
|
|
|
// https://github.com/MrAlex94/Waterfox-Old/blob/master/media/libstagefright/frameworks/av/media/libstagefright/MediaDefs.cpp
|
|
|
|
mMediaRecorder.setVideoFrameRate(stub.videoFrameRate); |
|
|
|
String audioType; |
|
|
|
|
|
|
|
switch (mProfile.audioCodec) { |
|
|
|
|
|
|
|
case MediaRecorder.AudioEncoder.AMR_NB: audioType = "audio/3gpp"; break; |
|
|
|
|
|
|
|
case MediaRecorder.AudioEncoder.AMR_WB: audioType = "audio/amr-wb"; break; |
|
|
|
|
|
|
|
case MediaRecorder.AudioEncoder.AAC: |
|
|
|
|
|
|
|
case MediaRecorder.AudioEncoder.HE_AAC: |
|
|
|
|
|
|
|
case MediaRecorder.AudioEncoder.AAC_ELD: audioType = "audio/mp4a-latm"; break; |
|
|
|
|
|
|
|
case MediaRecorder.AudioEncoder.VORBIS: audioType = "audio/vorbis"; break; |
|
|
|
|
|
|
|
case MediaRecorder.AudioEncoder.DEFAULT: |
|
|
|
|
|
|
|
default: audioType = "audio/3gpp"; |
|
|
|
} |
|
|
|
} |
|
|
|
mMediaRecorder.setVideoSize(size.getWidth(), size.getHeight()); |
|
|
|
|
|
|
|
switch (stub.videoCodec) { |
|
|
|
// Get the video mime type
|
|
|
|
case H_263: mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); break; |
|
|
|
// https://android.googlesource.com/platform/frameworks/av/+/master/media/libmediaplayerservice/StagefrightRecorder.cpp#1650
|
|
|
|
case H_264: mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); break; |
|
|
|
// https://github.com/MrAlex94/Waterfox-Old/blob/master/media/libstagefright/frameworks/av/media/libstagefright/MediaDefs.cpp
|
|
|
|
case DEVICE_DEFAULT: mMediaRecorder.setVideoEncoder(mProfile.videoCodec); break; |
|
|
|
String videoType; |
|
|
|
|
|
|
|
if (stub.videoCodec == VideoCodec.H_264) mProfile.videoCodec = MediaRecorder.VideoEncoder.H264; |
|
|
|
|
|
|
|
if (stub.videoCodec == VideoCodec.H_263) mProfile.videoCodec = MediaRecorder.VideoEncoder.H263; |
|
|
|
|
|
|
|
switch (mProfile.videoCodec) { |
|
|
|
|
|
|
|
case MediaRecorder.VideoEncoder.H263: videoType = "video/3gpp"; break; |
|
|
|
|
|
|
|
case MediaRecorder.VideoEncoder.H264: videoType = "video/avc"; break; |
|
|
|
|
|
|
|
case MediaRecorder.VideoEncoder.MPEG_4_SP: videoType = "video/mp4v-es"; break; |
|
|
|
|
|
|
|
case MediaRecorder.VideoEncoder.VP8: videoType = "video/x-vnd.on2.vp8"; break; |
|
|
|
|
|
|
|
case MediaRecorder.VideoEncoder.HEVC: videoType = "video/hevc"; break; |
|
|
|
|
|
|
|
case MediaRecorder.VideoEncoder.DEFAULT: |
|
|
|
|
|
|
|
default: videoType = "video/avc"; |
|
|
|
} |
|
|
|
} |
|
|
|
if (stub.videoBitRate <= 0) { |
|
|
|
|
|
|
|
mMediaRecorder.setVideoEncodingBitRate(mProfile.videoBitRate); |
|
|
|
// Merge stub and profile
|
|
|
|
stub.videoBitRate = mProfile.videoBitRate; |
|
|
|
stub.videoFrameRate = stub.videoFrameRate > 0 ? stub.videoFrameRate : mProfile.videoFrameRate; |
|
|
|
} else { |
|
|
|
stub.videoBitRate = stub.videoBitRate > 0 ? stub.videoBitRate : mProfile.videoBitRate; |
|
|
|
mMediaRecorder.setVideoEncodingBitRate(stub.videoBitRate); |
|
|
|
if (hasAudio) { |
|
|
|
|
|
|
|
stub.audioBitRate = stub.audioBitRate > 0 ? stub.audioBitRate : mProfile.audioBitRate; |
|
|
|
} |
|
|
|
} |
|
|
|
if (stub.audio == Audio.ON || stub.audio == Audio.MONO || stub.audio == Audio.STEREO) { |
|
|
|
|
|
|
|
|
|
|
|
// Check DeviceEncoders support
|
|
|
|
|
|
|
|
DeviceEncoders encoders = new DeviceEncoders(videoType, audioType, DeviceEncoders.MODE_TAKE_FIRST); |
|
|
|
|
|
|
|
boolean flip = stub.rotation % 180 != 0; |
|
|
|
|
|
|
|
if (flip) stub.size = stub.size.flip(); |
|
|
|
|
|
|
|
stub.size = encoders.getSupportedVideoSize(stub.size); |
|
|
|
|
|
|
|
stub.videoBitRate = encoders.getSupportedVideoBitRate(stub.videoBitRate); |
|
|
|
|
|
|
|
stub.audioBitRate = encoders.getSupportedAudioBitRate(stub.audioBitRate); |
|
|
|
|
|
|
|
stub.videoFrameRate = encoders.getSupportedVideoFrameRate(stub.size, stub.videoFrameRate); |
|
|
|
|
|
|
|
if (flip) stub.size = stub.size.flip(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set video params
|
|
|
|
|
|
|
|
mMediaRecorder.setVideoSize( |
|
|
|
|
|
|
|
flip ? stub.size.getHeight() : stub.size.getWidth(), |
|
|
|
|
|
|
|
flip ? stub.size.getWidth() : stub.size.getHeight()); |
|
|
|
|
|
|
|
mMediaRecorder.setVideoFrameRate(stub.videoFrameRate); |
|
|
|
|
|
|
|
mMediaRecorder.setVideoEncoder(mProfile.videoCodec); |
|
|
|
|
|
|
|
mMediaRecorder.setVideoEncodingBitRate(stub.videoBitRate); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set audio params
|
|
|
|
|
|
|
|
if (hasAudio) { |
|
|
|
if (stub.audio == Audio.ON) { |
|
|
|
if (stub.audio == Audio.ON) { |
|
|
|
mMediaRecorder.setAudioChannels(mProfile.audioChannels); |
|
|
|
mMediaRecorder.setAudioChannels(mProfile.audioChannels); |
|
|
|
} else if (stub.audio == Audio.MONO) { |
|
|
|
} else if (stub.audio == Audio.MONO) { |
|
|
|
mMediaRecorder.setAudioChannels(1); |
|
|
|
mMediaRecorder.setAudioChannels(1); |
|
|
|
} else //noinspection ConstantConditions
|
|
|
|
} else if (stub.audio == Audio.STEREO) { |
|
|
|
if (stub.audio == Audio.STEREO) { |
|
|
|
|
|
|
|
mMediaRecorder.setAudioChannels(2); |
|
|
|
mMediaRecorder.setAudioChannels(2); |
|
|
|
} |
|
|
|
} |
|
|
|
mMediaRecorder.setAudioSamplingRate(mProfile.audioSampleRate); |
|
|
|
mMediaRecorder.setAudioSamplingRate(mProfile.audioSampleRate); |
|
|
|
mMediaRecorder.setAudioEncoder(mProfile.audioCodec); |
|
|
|
mMediaRecorder.setAudioEncoder(mProfile.audioCodec); |
|
|
|
if (stub.audioBitRate <= 0) { |
|
|
|
mMediaRecorder.setAudioEncodingBitRate(mProfile.audioBitRate); |
|
|
|
mMediaRecorder.setAudioEncodingBitRate(mProfile.audioBitRate); |
|
|
|
|
|
|
|
stub.audioBitRate = mProfile.audioBitRate; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
mMediaRecorder.setAudioEncodingBitRate(stub.audioBitRate); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set other params
|
|
|
|
if (stub.location != null) { |
|
|
|
if (stub.location != null) { |
|
|
|
mMediaRecorder.setLocation( |
|
|
|
mMediaRecorder.setLocation( |
|
|
|
(float) stub.location.getLatitude(), |
|
|
|
(float) stub.location.getLatitude(), |
|
|
@ -113,6 +151,7 @@ public abstract class FullVideoRecorder extends VideoRecorder { |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Prepare the Recorder
|
|
|
|
try { |
|
|
|
try { |
|
|
|
mMediaRecorder.prepare(); |
|
|
|
mMediaRecorder.prepare(); |
|
|
|
mMediaRecorderPrepared = true; |
|
|
|
mMediaRecorderPrepared = true; |
|
|
|