init
This commit is contained in:
commit
e2dc633112
21
package.json
Normal file
21
package.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "capture-cordova-plugin",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Video or Photo Capture Cordova Plugin",
|
||||||
|
"cordova": {
|
||||||
|
"id": "capture-cordova-plugin",
|
||||||
|
"platforms": [
|
||||||
|
"android"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://m.shuto.cn:8680/center/capture-cordova-plugin.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"ecosystem:cordova",
|
||||||
|
"cordova-android"
|
||||||
|
],
|
||||||
|
"author": "shuto",
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
35
plugin.xml
Normal file
35
plugin.xml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<plugin id="capture-cordova-plugin" version="1.0.0"
|
||||||
|
xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<name>Capture Plugin</name>
|
||||||
|
|
||||||
|
<js-module name="capture-cordova-plugin" src="www/capture.js">
|
||||||
|
<clobbers target="capture" />
|
||||||
|
</js-module>
|
||||||
|
|
||||||
|
<platform name="android">
|
||||||
|
<config-file parent="/*" target="res/xml/config.xml">
|
||||||
|
<feature name="capture-cordova-plugin">
|
||||||
|
<param name="android-package" value="cn.shuto.plugin.capture.CaptureCordovaPlugin" />
|
||||||
|
</feature>
|
||||||
|
</config-file>
|
||||||
|
<config-file target="AndroidManifest.xml" parent="/*">
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
</config-file>
|
||||||
|
<config-file target="AndroidManifest.xml" parent="application">
|
||||||
|
<activity android:name="com.mabeijianxi.smallvideorecord2.MediaRecorderActivity" android:clearTaskOnLaunch="true" android:configChanges="orientation|keyboardHidden|screenSize" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden" android:exported="false"/>
|
||||||
|
<provider android:name="org.apache.cordova.camera.FileProvider" android:authorities="${applicationId}.cordova.plugin.camera.provider" android:exported="false" android:grantUriPermissions="true">
|
||||||
|
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/camera_provider_paths"/>
|
||||||
|
</provider>
|
||||||
|
</config-file>
|
||||||
|
<config-file target="AndroidManifest.xml" parent="/manifest">
|
||||||
|
<uses-permission android:name="android.permission.CAMERA"/>
|
||||||
|
<uses-permission android:name="android.permission.FLASHLIGHT"/>
|
||||||
|
<uses-feature android:name="android.hardware.camera" android:required="true"/>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
<source-file src="src/android/CaptureCordovaPlugin.java" target-dir="src/cn/shuto/plugin/capture" />
|
||||||
|
<framework custom="true" src="src/android/mobile-ffmpeg-x2.gradle" type="gradleReference" />
|
||||||
|
</platform>
|
||||||
|
</plugin>
|
31
src/android/CaptureCordovaPlugin.java
Normal file
31
src/android/CaptureCordovaPlugin.java
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package cn.shuto.plugin.capture;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaPlugin;
|
||||||
|
import org.apache.cordova.CallbackContext;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class echoes a string called from JavaScript.
|
||||||
|
*/
|
||||||
|
public class CaptureCordovaPlugin extends CordovaPlugin {
|
||||||
|
public static final int REQUEST_CODE = 0x777578;
|
||||||
|
private CallbackContext callbackContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
||||||
|
this.callbackContext = callbackContext;
|
||||||
|
JSONObject param = args.optJSONObject(0);
|
||||||
|
if (action.equals("capture")) {
|
||||||
|
this.capture(param, callbackContext);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void capture(JSONObject param, CallbackContext callbackContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
704
src/android/MediaRecorderActivity.java
Normal file
704
src/android/MediaRecorderActivity.java
Normal file
@ -0,0 +1,704 @@
|
|||||||
|
package com.mabeijianxi.smallvideorecord2;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.CheckedTextView;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.mabeijianxi.smallvideorecord2.model.MediaObject;
|
||||||
|
import com.mabeijianxi.smallvideorecord2.model.MediaRecorderConfig;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import static com.mabeijianxi.smallvideorecord2.R.id.bottom_layout;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频录制
|
||||||
|
*/
|
||||||
|
public class MediaRecorderActivity extends Activity implements
|
||||||
|
MediaRecorderBase.OnErrorListener, OnClickListener, MediaRecorderBase.OnPreparedListener,
|
||||||
|
MediaRecorderBase.OnEncodeListener {
|
||||||
|
|
||||||
|
private int RECORD_TIME_MIN = (int) (1.5f * 1000);
|
||||||
|
/**
|
||||||
|
* 录制最长时间
|
||||||
|
*/
|
||||||
|
private int RECORD_TIME_MAX = 6 * 1000;
|
||||||
|
/**
|
||||||
|
* 刷新进度条
|
||||||
|
*/
|
||||||
|
private static final int HANDLE_INVALIDATE_PROGRESS = 0;
|
||||||
|
/**
|
||||||
|
* 延迟拍摄停止
|
||||||
|
*/
|
||||||
|
private static final int HANDLE_STOP_RECORD = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下一步
|
||||||
|
*/
|
||||||
|
private ImageView mTitleNext;
|
||||||
|
/**
|
||||||
|
* 前后摄像头切换
|
||||||
|
*/
|
||||||
|
private CheckBox mCameraSwitch;
|
||||||
|
/**
|
||||||
|
* 回删按钮、延时按钮、滤镜按钮
|
||||||
|
*/
|
||||||
|
private CheckedTextView mRecordDelete;
|
||||||
|
/**
|
||||||
|
* 闪光灯
|
||||||
|
*/
|
||||||
|
private CheckBox mRecordLed;
|
||||||
|
/**
|
||||||
|
* 拍摄按钮
|
||||||
|
*/
|
||||||
|
private TextView mRecordController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 底部条
|
||||||
|
*/
|
||||||
|
private RelativeLayout mBottomLayout;
|
||||||
|
/**
|
||||||
|
* 摄像头数据显示画布
|
||||||
|
*/
|
||||||
|
private SurfaceView mSurfaceView;
|
||||||
|
/**
|
||||||
|
* 录制进度
|
||||||
|
*/
|
||||||
|
private ProgressView mProgressView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SDK视频录制对象
|
||||||
|
*/
|
||||||
|
private MediaRecorderBase mMediaRecorder;
|
||||||
|
/**
|
||||||
|
* 视频信息
|
||||||
|
*/
|
||||||
|
private MediaObject mMediaObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是点击状态
|
||||||
|
*/
|
||||||
|
private volatile boolean mPressedStatus;
|
||||||
|
/**
|
||||||
|
* 是否已经释放
|
||||||
|
*/
|
||||||
|
private volatile boolean mReleased;
|
||||||
|
/**
|
||||||
|
* 视屏地址
|
||||||
|
*/
|
||||||
|
public final static String VIDEO_URI = "video_uri";
|
||||||
|
/**
|
||||||
|
* 本次视频保存的文件夹地址
|
||||||
|
*/
|
||||||
|
public final static String OUTPUT_DIRECTORY = "output_directory";
|
||||||
|
/**
|
||||||
|
* 视屏截图地址
|
||||||
|
*/
|
||||||
|
public final static String VIDEO_SCREENSHOT = "video_screenshot";
|
||||||
|
/**
|
||||||
|
* 录制完成后需要跳转的activity
|
||||||
|
*/
|
||||||
|
public final static String OVER_ACTIVITY_NAME = "over_activity_name";
|
||||||
|
/**
|
||||||
|
* 最大录制时间的key
|
||||||
|
*/
|
||||||
|
public final static String MEDIA_RECORDER_MAX_TIME_KEY = "media_recorder_max_time_key";
|
||||||
|
/**
|
||||||
|
* 最小录制时间的key
|
||||||
|
*/
|
||||||
|
public final static String MEDIA_RECORDER_MIN_TIME_KEY = "media_recorder_min_time_key";
|
||||||
|
/**
|
||||||
|
* 录制配置key
|
||||||
|
*/
|
||||||
|
public final static String MEDIA_RECORDER_CONFIG_KEY = "media_recorder_config_key";
|
||||||
|
|
||||||
|
private boolean GO_HOME;
|
||||||
|
private boolean startState;
|
||||||
|
private boolean NEED_FULL_SCREEN = false;
|
||||||
|
private RelativeLayout title_layout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context
|
||||||
|
* @param overGOActivityName 录制结束后需要跳转的Activity全类名
|
||||||
|
*/
|
||||||
|
public static void goSmallVideoRecorder(Activity context, String overGOActivityName, MediaRecorderConfig mediaRecorderConfig) {
|
||||||
|
context.startActivity(new Intent(context, MediaRecorderActivity.class).putExtra(OVER_ACTIVITY_NAME, overGOActivityName).putExtra(MEDIA_RECORDER_CONFIG_KEY, mediaRecorderConfig));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // 防止锁屏
|
||||||
|
initData();
|
||||||
|
loadViews();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData() {
|
||||||
|
Intent intent = getIntent();
|
||||||
|
MediaRecorderConfig mediaRecorderConfig = intent.getParcelableExtra(MEDIA_RECORDER_CONFIG_KEY);
|
||||||
|
if (mediaRecorderConfig == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NEED_FULL_SCREEN = mediaRecorderConfig.getFullScreen();
|
||||||
|
RECORD_TIME_MAX = mediaRecorderConfig.getRecordTimeMax();
|
||||||
|
RECORD_TIME_MIN = mediaRecorderConfig.getRecordTimeMin();
|
||||||
|
MediaRecorderBase.MAX_FRAME_RATE = mediaRecorderConfig.getMaxFrameRate();
|
||||||
|
MediaRecorderBase.NEED_FULL_SCREEN = NEED_FULL_SCREEN;
|
||||||
|
MediaRecorderBase.MIN_FRAME_RATE = mediaRecorderConfig.getMinFrameRate();
|
||||||
|
MediaRecorderBase.SMALL_VIDEO_HEIGHT = mediaRecorderConfig.getSmallVideoHeight();
|
||||||
|
MediaRecorderBase.SMALL_VIDEO_WIDTH = mediaRecorderConfig.getSmallVideoWidth();
|
||||||
|
MediaRecorderBase.mVideoBitrate = mediaRecorderConfig.getVideoBitrate();
|
||||||
|
MediaRecorderBase.CAPTURE_THUMBNAILS_TIME = mediaRecorderConfig.getCaptureThumbnailsTime();
|
||||||
|
GO_HOME = mediaRecorderConfig.isGO_HOME();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载视图
|
||||||
|
*/
|
||||||
|
private void loadViews() {
|
||||||
|
setContentView(R.layout.activity_media_recorder);
|
||||||
|
// ~~~ 绑定控件
|
||||||
|
mSurfaceView = (SurfaceView) findViewById(R.id.record_preview);
|
||||||
|
title_layout = (RelativeLayout) findViewById(R.id.title_layout);
|
||||||
|
mCameraSwitch = (CheckBox) findViewById(R.id.record_camera_switcher);
|
||||||
|
mTitleNext = (ImageView) findViewById(R.id.title_next);
|
||||||
|
mProgressView = (ProgressView) findViewById(R.id.record_progress);
|
||||||
|
mRecordDelete = (CheckedTextView) findViewById(R.id.record_delete);
|
||||||
|
mRecordController = (TextView) findViewById(R.id.record_controller);
|
||||||
|
mBottomLayout = (RelativeLayout) findViewById(bottom_layout);
|
||||||
|
mRecordLed = (CheckBox) findViewById(R.id.record_camera_led);
|
||||||
|
|
||||||
|
// ~~~ 绑定事件
|
||||||
|
/*if (DeviceUtils.hasICS())
|
||||||
|
mSurfaceView.setOnTouchListener(mOnSurfaveViewTouchListener);*/
|
||||||
|
|
||||||
|
mTitleNext.setOnClickListener(this);
|
||||||
|
findViewById(R.id.title_back).setOnClickListener(this);
|
||||||
|
// mRecordDelete.setOnClickListener(this);
|
||||||
|
mRecordController.setOnTouchListener(mOnVideoControllerTouchListener);
|
||||||
|
|
||||||
|
// ~~~ 设置数据
|
||||||
|
|
||||||
|
// 是否支持前置摄像头
|
||||||
|
if (MediaRecorderBase.isSupportFrontCamera()) {
|
||||||
|
mCameraSwitch.setOnClickListener(this);
|
||||||
|
} else {
|
||||||
|
mCameraSwitch.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
// 是否支持闪光灯
|
||||||
|
if (DeviceUtils.isSupportCameraLedFlash(getPackageManager())) {
|
||||||
|
mRecordLed.setOnClickListener(this);
|
||||||
|
} else {
|
||||||
|
mRecordLed.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mProgressView.setMaxDuration(RECORD_TIME_MAX);
|
||||||
|
mProgressView.setMinTime(RECORD_TIME_MIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化画布
|
||||||
|
*/
|
||||||
|
private void initSurfaceView() {
|
||||||
|
if (NEED_FULL_SCREEN) {
|
||||||
|
mBottomLayout.setBackgroundColor(0);
|
||||||
|
title_layout.setBackgroundColor(getResources().getColor(R.color.full_title_color));
|
||||||
|
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mSurfaceView
|
||||||
|
.getLayoutParams();
|
||||||
|
lp.setMargins(0,0,0,0);
|
||||||
|
mSurfaceView.setLayoutParams(lp);
|
||||||
|
mProgressView.setBackgroundColor(getResources().getColor(R.color.full_progress_color));
|
||||||
|
} else {
|
||||||
|
final int w = DeviceUtils.getScreenWidth(this);
|
||||||
|
((RelativeLayout.LayoutParams) mBottomLayout.getLayoutParams()).topMargin = (int) (w / (MediaRecorderBase.SMALL_VIDEO_HEIGHT / (MediaRecorderBase.SMALL_VIDEO_WIDTH * 1.0f)));
|
||||||
|
int width = w;
|
||||||
|
int height = (int) (w * ((MediaRecorderBase.mSupportedPreviewWidth * 1.0f) / MediaRecorderBase.SMALL_VIDEO_HEIGHT));
|
||||||
|
//
|
||||||
|
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mSurfaceView
|
||||||
|
.getLayoutParams();
|
||||||
|
lp.width = width;
|
||||||
|
lp.height = height;
|
||||||
|
mSurfaceView.setLayoutParams(lp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化拍摄SDK
|
||||||
|
*/
|
||||||
|
private void initMediaRecorder() {
|
||||||
|
mMediaRecorder = new MediaRecorderNative();
|
||||||
|
|
||||||
|
mMediaRecorder.setOnErrorListener(this);
|
||||||
|
mMediaRecorder.setOnEncodeListener(this);
|
||||||
|
mMediaRecorder.setOnPreparedListener(this);
|
||||||
|
|
||||||
|
File f = new File(JianXiCamera.getVideoCachePath());
|
||||||
|
if (!FileUtils.checkFile(f)) {
|
||||||
|
f.mkdirs();
|
||||||
|
}
|
||||||
|
String key = String.valueOf(System.currentTimeMillis());
|
||||||
|
mMediaObject = mMediaRecorder.setOutputDirectory(key,
|
||||||
|
JianXiCamera.getVideoCachePath() + key);
|
||||||
|
mMediaRecorder.setSurfaceHolder(mSurfaceView.getHolder());
|
||||||
|
mMediaRecorder.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击屏幕录制
|
||||||
|
*/
|
||||||
|
private View.OnTouchListener mOnVideoControllerTouchListener = new View.OnTouchListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
if (mMediaRecorder == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
// 检测是否手动对焦
|
||||||
|
// 判断是否已经超时
|
||||||
|
if (mMediaObject.getDuration() >= RECORD_TIME_MAX) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消回删
|
||||||
|
if (cancelDelete())
|
||||||
|
return true;
|
||||||
|
if (!startState) {
|
||||||
|
startState = true;
|
||||||
|
startRecord();
|
||||||
|
} else {
|
||||||
|
mMediaObject.buildMediaPart(mMediaRecorder.mCameraId);
|
||||||
|
mProgressView.setData(mMediaObject);
|
||||||
|
setStartUI();
|
||||||
|
mMediaRecorder.setRecordState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
|
||||||
|
mMediaRecorder.setRecordState(false);
|
||||||
|
if (mMediaObject.getDuration() >= RECORD_TIME_MAX) {
|
||||||
|
mTitleNext.performClick();
|
||||||
|
} else {
|
||||||
|
mMediaRecorder.setStopDate();
|
||||||
|
setStopUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 暂停
|
||||||
|
/* if (mPressedStatus) {
|
||||||
|
|
||||||
|
// 检测是否已经完成
|
||||||
|
if (mMediaObject.getDuration() >= RECORD_TIME_MAX) {
|
||||||
|
mTitleNext.performClick();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
if (mMediaRecorder == null) {
|
||||||
|
initMediaRecorder();
|
||||||
|
} else {
|
||||||
|
mRecordLed.setChecked(false);
|
||||||
|
mMediaRecorder.prepare();
|
||||||
|
mProgressView.setData(mMediaObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
stopRecord();
|
||||||
|
if (!mReleased) {
|
||||||
|
if (mMediaRecorder != null)
|
||||||
|
mMediaRecorder.release();
|
||||||
|
}
|
||||||
|
mReleased = false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始录制
|
||||||
|
*/
|
||||||
|
private void startRecord() {
|
||||||
|
if (mMediaRecorder != null) {
|
||||||
|
|
||||||
|
MediaObject.MediaPart part = mMediaRecorder.startRecord();
|
||||||
|
if (part == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mProgressView.setData(mMediaObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
setStartUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setStartUI() {
|
||||||
|
mPressedStatus = true;
|
||||||
|
// TODO 开始录制的图标
|
||||||
|
mRecordController.animate().scaleX(0.8f).scaleY(0.8f).setDuration(500).start();
|
||||||
|
|
||||||
|
|
||||||
|
if (mHandler != null) {
|
||||||
|
mHandler.removeMessages(HANDLE_INVALIDATE_PROGRESS);
|
||||||
|
mHandler.sendEmptyMessage(HANDLE_INVALIDATE_PROGRESS);
|
||||||
|
|
||||||
|
mHandler.removeMessages(HANDLE_STOP_RECORD);
|
||||||
|
mHandler.sendEmptyMessageDelayed(HANDLE_STOP_RECORD,
|
||||||
|
RECORD_TIME_MAX - mMediaObject.getDuration());
|
||||||
|
}
|
||||||
|
// mRecordDelete.setVisibility(View.GONE);
|
||||||
|
mCameraSwitch.setEnabled(false);
|
||||||
|
mRecordLed.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
/*if (mRecordDelete != null && mRecordDelete.isChecked()) {
|
||||||
|
cancelDelete();
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (mMediaObject != null && mMediaObject.getDuration() > 1) {
|
||||||
|
// 未转码
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setTitle(R.string.hint)
|
||||||
|
.setMessage(R.string.record_camera_exit_dialog_message)
|
||||||
|
.setNegativeButton(
|
||||||
|
R.string.record_camera_cancel_dialog_yes,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog,
|
||||||
|
int which) {
|
||||||
|
mMediaObject.delete();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.setPositiveButton(R.string.record_camera_cancel_dialog_no,
|
||||||
|
null).setCancelable(false).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMediaObject != null)
|
||||||
|
mMediaObject.delete();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止录制
|
||||||
|
*/
|
||||||
|
private void stopRecord() {
|
||||||
|
if (mMediaRecorder != null) {
|
||||||
|
mMediaRecorder.stopRecord();
|
||||||
|
}
|
||||||
|
setStopUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setStopUI() {
|
||||||
|
mPressedStatus = false;
|
||||||
|
mRecordController.animate().scaleX(1).scaleY(1).setDuration(500).start();
|
||||||
|
|
||||||
|
|
||||||
|
// mRecordDelete.setVisibility(View.VISIBLE);
|
||||||
|
mCameraSwitch.setEnabled(true);
|
||||||
|
mRecordLed.setEnabled(true);
|
||||||
|
|
||||||
|
mHandler.removeMessages(HANDLE_STOP_RECORD);
|
||||||
|
checkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
final int id = v.getId();
|
||||||
|
if (mHandler.hasMessages(HANDLE_STOP_RECORD)) {
|
||||||
|
mHandler.removeMessages(HANDLE_STOP_RECORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理开启回删后其他点击操作
|
||||||
|
if (id != R.id.record_delete) {
|
||||||
|
if (mMediaObject != null) {
|
||||||
|
MediaObject.MediaPart part = mMediaObject.getCurrentPart();
|
||||||
|
if (part != null) {
|
||||||
|
if (part.remove) {
|
||||||
|
part.remove = false;
|
||||||
|
// mRecordDelete.setChecked(false);
|
||||||
|
if (mProgressView != null)
|
||||||
|
mProgressView.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == R.id.title_back) {
|
||||||
|
onBackPressed();
|
||||||
|
} else if (id == R.id.record_camera_switcher) {// 前后摄像头切换
|
||||||
|
if (mRecordLed.isChecked()) {
|
||||||
|
if (mMediaRecorder != null) {
|
||||||
|
mMediaRecorder.toggleFlashMode();
|
||||||
|
}
|
||||||
|
mRecordLed.setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMediaRecorder != null) {
|
||||||
|
mMediaRecorder.switchCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMediaRecorder.isFrontCamera()) {
|
||||||
|
mRecordLed.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
mRecordLed.setEnabled(true);
|
||||||
|
}
|
||||||
|
} else if (id == R.id.record_camera_led) {// 闪光灯
|
||||||
|
// 开启前置摄像头以后不支持开启闪光灯
|
||||||
|
if (mMediaRecorder != null) {
|
||||||
|
if (mMediaRecorder.isFrontCamera()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mMediaRecorder != null) {
|
||||||
|
mMediaRecorder.toggleFlashMode();
|
||||||
|
}
|
||||||
|
} else if (id == R.id.title_next) {// 停止录制
|
||||||
|
stopRecord();
|
||||||
|
/*finish();
|
||||||
|
overridePendingTransition(R.anim.push_bottom_in,
|
||||||
|
R.anim.push_bottom_out);*/
|
||||||
|
} else if (id == R.id.record_delete) {
|
||||||
|
// 取消回删
|
||||||
|
if (mMediaObject != null) {
|
||||||
|
MediaObject.MediaPart part = mMediaObject.getCurrentPart();
|
||||||
|
if (part != null) {
|
||||||
|
if (part.remove) {
|
||||||
|
part.remove = false;
|
||||||
|
mMediaObject.removePart(part, true);
|
||||||
|
// mRecordDelete.setChecked(false);
|
||||||
|
} else {
|
||||||
|
part.remove = true;
|
||||||
|
// mRecordDelete.setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mProgressView != null)
|
||||||
|
mProgressView.invalidate();
|
||||||
|
|
||||||
|
// 检测按钮状态
|
||||||
|
checkStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消回删
|
||||||
|
*/
|
||||||
|
private boolean cancelDelete() {
|
||||||
|
if (mMediaObject != null) {
|
||||||
|
MediaObject.MediaPart part = mMediaObject.getCurrentPart();
|
||||||
|
if (part != null && part.remove) {
|
||||||
|
part.remove = false;
|
||||||
|
// mRecordDelete.setChecked(false);
|
||||||
|
|
||||||
|
if (mProgressView != null)
|
||||||
|
mProgressView.invalidate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查录制时间,显示/隐藏下一步按钮
|
||||||
|
*/
|
||||||
|
private int checkStatus() {
|
||||||
|
int duration = 0;
|
||||||
|
if (!isFinishing() && mMediaObject != null) {
|
||||||
|
duration = mMediaObject.getDuration();
|
||||||
|
if (duration < RECORD_TIME_MIN) {
|
||||||
|
if (duration == 0) {
|
||||||
|
mCameraSwitch.setVisibility(View.VISIBLE);
|
||||||
|
// mRecordDelete.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
mCameraSwitch.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
// 视频必须大于3秒
|
||||||
|
if (mTitleNext.getVisibility() != View.INVISIBLE)
|
||||||
|
mTitleNext.setVisibility(View.INVISIBLE);
|
||||||
|
} else {
|
||||||
|
// 下一步
|
||||||
|
if (mTitleNext.getVisibility() != View.VISIBLE) {
|
||||||
|
mTitleNext.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Handler mHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case HANDLE_INVALIDATE_PROGRESS:
|
||||||
|
if (mMediaRecorder != null && !isFinishing()) {
|
||||||
|
if (mMediaObject != null && mMediaObject.getMedaParts() != null && mMediaObject.getDuration() >= RECORD_TIME_MAX) {
|
||||||
|
mTitleNext.performClick();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mProgressView != null)
|
||||||
|
mProgressView.invalidate();
|
||||||
|
// if (mPressedStatus)
|
||||||
|
// titleText.setText(String.format("%.1f",
|
||||||
|
// mMediaRecorder.getDuration() / 1000F));
|
||||||
|
if (mPressedStatus)
|
||||||
|
sendEmptyMessageDelayed(0, 30);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEncodeStart() {
|
||||||
|
showProgress("", getString(R.string.record_camera_progress_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEncodeProgress(int progress) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转码完成
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onEncodeComplete() {
|
||||||
|
hideProgress();
|
||||||
|
Intent intent = null;
|
||||||
|
try {
|
||||||
|
intent = new Intent(this, Class.forName(getIntent().getStringExtra(OVER_ACTIVITY_NAME)));
|
||||||
|
intent.putExtra(MediaRecorderActivity.OUTPUT_DIRECTORY, mMediaObject.getOutputDirectory());
|
||||||
|
intent.putExtra(MediaRecorderActivity.VIDEO_URI, mMediaObject.getOutputTempTranscodingVideoPath());
|
||||||
|
intent.putExtra(MediaRecorderActivity.VIDEO_SCREENSHOT, mMediaObject.getOutputVideoThumbPath());
|
||||||
|
intent.putExtra("go_home", GO_HOME);
|
||||||
|
startActivity(intent);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new IllegalArgumentException("需要传入录制完成后跳转的Activity的全类名");
|
||||||
|
}
|
||||||
|
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转码失败 检查sdcard是否可用,检查分块是否存在
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onEncodeError() {
|
||||||
|
hideProgress();
|
||||||
|
Toast.makeText(this, R.string.record_video_transcoding_faild,
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoError(int what, int extra) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAudioError(int what, String message) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrepared() {
|
||||||
|
initSurfaceView();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onFinished() {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ProgressDialog mProgressDialog;
|
||||||
|
|
||||||
|
public ProgressDialog showProgress(String title, String message) {
|
||||||
|
return showProgress(title, message, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgressDialog showProgress(String title, String message, int theme) {
|
||||||
|
if (mProgressDialog == null) {
|
||||||
|
if (theme > 0)
|
||||||
|
mProgressDialog = new ProgressDialog(this, theme);
|
||||||
|
else
|
||||||
|
mProgressDialog = new ProgressDialog(this);
|
||||||
|
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
|
||||||
|
mProgressDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
mProgressDialog.setCanceledOnTouchOutside(false);// 不能取消
|
||||||
|
mProgressDialog.setCancelable(false);
|
||||||
|
mProgressDialog.setIndeterminate(true);// 设置进度条是否不明确
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(title))
|
||||||
|
mProgressDialog.setTitle(title);
|
||||||
|
mProgressDialog.setMessage(message);
|
||||||
|
mProgressDialog.show();
|
||||||
|
return mProgressDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hideProgress() {
|
||||||
|
if (mProgressDialog != null) {
|
||||||
|
mProgressDialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
mMediaRecorder.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
if (mMediaRecorder instanceof MediaRecorderNative) {
|
||||||
|
((MediaRecorderNative) mMediaRecorder).activityStop();
|
||||||
|
}
|
||||||
|
hideProgress();
|
||||||
|
mProgressDialog = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
285
src/android/MediaRecorderConfig.java
Normal file
285
src/android/MediaRecorderConfig.java
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
package com.mabeijianxi.smallvideorecord2.model;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by jian on 2016/8/25 17:03
|
||||||
|
* https://github.com/mabeijianxi
|
||||||
|
* mabeijianxi@gmail.com
|
||||||
|
*/
|
||||||
|
public final class MediaRecorderConfig implements Parcelable {
|
||||||
|
|
||||||
|
private final boolean FULL_SCREEN;
|
||||||
|
/**
|
||||||
|
* 录制时间
|
||||||
|
*/
|
||||||
|
private final int RECORD_TIME_MAX;
|
||||||
|
/**
|
||||||
|
* 最少录制时间
|
||||||
|
*/
|
||||||
|
private final int RECORD_TIME_MIN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小视频高度
|
||||||
|
* <p>注意:宽度不能随意传,需要传送手机摄像头手支持录制的视频高度,注意是高度(因为会选择,具体原因不多解释)。
|
||||||
|
* 获取摄像头所支持的尺寸的方式是{@link android.graphics.Camera#getSupportedPreviewSizes()}
|
||||||
|
* 一般支持的尺寸的高度有:240、480、720、1080等,具体值请用以上方法获取</p>
|
||||||
|
*/
|
||||||
|
private final int SMALL_VIDEO_HEIGHT;
|
||||||
|
/**
|
||||||
|
* 小视频宽度
|
||||||
|
*/
|
||||||
|
private final int SMALL_VIDEO_WIDTH;
|
||||||
|
/**
|
||||||
|
* 最大帧率
|
||||||
|
*/
|
||||||
|
private final int MAX_FRAME_RATE;
|
||||||
|
/**
|
||||||
|
* 最小帧率
|
||||||
|
*/
|
||||||
|
private final int MIN_FRAME_RATE;
|
||||||
|
/**
|
||||||
|
* 视频码率
|
||||||
|
*/
|
||||||
|
private final int VIDEO_BITRATE;
|
||||||
|
/**
|
||||||
|
* 录制后会剪切一帧缩略图并保存,就是取时间轴上这个时间的画面
|
||||||
|
*/
|
||||||
|
private final int captureThumbnailsTime;
|
||||||
|
|
||||||
|
private final boolean GO_HOME;
|
||||||
|
|
||||||
|
private MediaRecorderConfig(Buidler buidler) {
|
||||||
|
this.FULL_SCREEN = buidler.FULL_SCREEN;
|
||||||
|
this.RECORD_TIME_MAX = buidler.RECORD_TIME_MAX;
|
||||||
|
this.RECORD_TIME_MIN = buidler.RECORD_TIME_MIN;
|
||||||
|
this.MAX_FRAME_RATE = buidler.MAX_FRAME_RATE;
|
||||||
|
this.captureThumbnailsTime = buidler.captureThumbnailsTime;
|
||||||
|
this.MIN_FRAME_RATE = buidler.MIN_FRAME_RATE;
|
||||||
|
this.SMALL_VIDEO_HEIGHT = buidler.SMALL_VIDEO_HEIGHT;
|
||||||
|
this.SMALL_VIDEO_WIDTH = buidler.SMALL_VIDEO_WIDTH;
|
||||||
|
this.VIDEO_BITRATE = buidler.VIDEO_BITRATE;
|
||||||
|
this.GO_HOME=buidler.GO_HOME;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MediaRecorderConfig(Parcel in) {
|
||||||
|
FULL_SCREEN = in.readByte() != 0;
|
||||||
|
RECORD_TIME_MAX = in.readInt();
|
||||||
|
RECORD_TIME_MIN = in.readInt();
|
||||||
|
SMALL_VIDEO_HEIGHT = in.readInt();
|
||||||
|
SMALL_VIDEO_WIDTH = in.readInt();
|
||||||
|
MAX_FRAME_RATE = in.readInt();
|
||||||
|
MIN_FRAME_RATE = in.readInt();
|
||||||
|
VIDEO_BITRATE = in.readInt();
|
||||||
|
captureThumbnailsTime = in.readInt();
|
||||||
|
GO_HOME = in.readByte() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<MediaRecorderConfig> CREATOR = new Creator<MediaRecorderConfig>() {
|
||||||
|
@Override
|
||||||
|
public MediaRecorderConfig createFromParcel(Parcel in) {
|
||||||
|
return new MediaRecorderConfig(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MediaRecorderConfig[] newArray(int size) {
|
||||||
|
return new MediaRecorderConfig[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public boolean isGO_HOME() {
|
||||||
|
return GO_HOME;
|
||||||
|
}
|
||||||
|
public boolean getFullScreen() {
|
||||||
|
return FULL_SCREEN;
|
||||||
|
}
|
||||||
|
public int getCaptureThumbnailsTime() {
|
||||||
|
return captureThumbnailsTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getMaxFrameRate() {
|
||||||
|
return MAX_FRAME_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinFrameRate() {
|
||||||
|
return MIN_FRAME_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRecordTimeMax() {
|
||||||
|
return RECORD_TIME_MAX;
|
||||||
|
}
|
||||||
|
public int getRecordTimeMin() {
|
||||||
|
return RECORD_TIME_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSmallVideoHeight() {
|
||||||
|
return SMALL_VIDEO_HEIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSmallVideoWidth() {
|
||||||
|
return SMALL_VIDEO_WIDTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int getVideoBitrate() {
|
||||||
|
return VIDEO_BITRATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeByte((byte) (FULL_SCREEN ? 1 : 0));
|
||||||
|
dest.writeInt(RECORD_TIME_MAX);
|
||||||
|
dest.writeInt(RECORD_TIME_MIN);
|
||||||
|
dest.writeInt(SMALL_VIDEO_HEIGHT);
|
||||||
|
dest.writeInt(SMALL_VIDEO_WIDTH);
|
||||||
|
dest.writeInt(MAX_FRAME_RATE);
|
||||||
|
dest.writeInt(MIN_FRAME_RATE);
|
||||||
|
dest.writeInt(VIDEO_BITRATE);
|
||||||
|
dest.writeInt(captureThumbnailsTime);
|
||||||
|
dest.writeByte((byte) (GO_HOME ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class Buidler {
|
||||||
|
/**
|
||||||
|
* 录制时间
|
||||||
|
*/
|
||||||
|
private int RECORD_TIME_MAX = 6 * 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小视频高度
|
||||||
|
* <p>注意:宽度不能随意传,需要传送手机摄像头手支持录制的视频高度,注意是高度(因为会选择,具体原因不多解释)。
|
||||||
|
* 获取摄像头所支持的尺寸的方式是{@link android.graphics.Camera#getSupportedPreviewSizes()}
|
||||||
|
* 一般支持的尺寸的高度有:240、480、720、1080等,具体值请用以上方法获取</p>
|
||||||
|
*/
|
||||||
|
private int SMALL_VIDEO_HEIGHT = 480;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小视频宽度
|
||||||
|
*/
|
||||||
|
private int SMALL_VIDEO_WIDTH = 360;
|
||||||
|
/**
|
||||||
|
* 最大帧率
|
||||||
|
*/
|
||||||
|
private int MAX_FRAME_RATE = 20;
|
||||||
|
/**
|
||||||
|
* 最小帧率
|
||||||
|
*/
|
||||||
|
private int MIN_FRAME_RATE = 8;
|
||||||
|
/**
|
||||||
|
* 视频码率//todo 注意传入>0的值后码率模式将从VBR变成CBR
|
||||||
|
*/
|
||||||
|
private int VIDEO_BITRATE;
|
||||||
|
/**
|
||||||
|
* 录制后会剪切一帧缩略图并保存,就是取时间轴上这个时间的画面
|
||||||
|
*/
|
||||||
|
private int captureThumbnailsTime = 1;
|
||||||
|
|
||||||
|
|
||||||
|
private boolean GO_HOME=false;
|
||||||
|
|
||||||
|
public int RECORD_TIME_MIN= (int) (1.5*1000);
|
||||||
|
|
||||||
|
private boolean FULL_SCREEN =false;
|
||||||
|
|
||||||
|
|
||||||
|
public MediaRecorderConfig build() {
|
||||||
|
return new MediaRecorderConfig(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param captureThumbnailsTime 录制后会剪切一帧缩略图并保存,就是取时间轴上这个时间的画面
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Buidler captureThumbnailsTime(int captureThumbnailsTime) {
|
||||||
|
this.captureThumbnailsTime = captureThumbnailsTime;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param MAX_FRAME_RATE 最大帧率(与视频清晰度、大小息息相关)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Buidler maxFrameRate(int MAX_FRAME_RATE) {
|
||||||
|
this.MAX_FRAME_RATE = MAX_FRAME_RATE;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param MIN_FRAME_RATE 最小帧率(与视频清晰度、大小息息相关)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Buidler minFrameRate(int MIN_FRAME_RATE) {
|
||||||
|
this.MIN_FRAME_RATE = MIN_FRAME_RATE;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param RECORD_TIME_MAX 录制时间
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Buidler recordTimeMax(int RECORD_TIME_MAX) {
|
||||||
|
this.RECORD_TIME_MAX = RECORD_TIME_MAX;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param RECORD_TIME_MIN 最少录制时间
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Buidler recordTimeMin(int RECORD_TIME_MIN) {
|
||||||
|
this.RECORD_TIME_MIN = RECORD_TIME_MIN;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param SMALL_VIDEO_HEIGHT
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Buidler smallVideoHeight(int SMALL_VIDEO_HEIGHT) {
|
||||||
|
this.SMALL_VIDEO_HEIGHT = SMALL_VIDEO_HEIGHT;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param SMALL_VIDEO_WIDTH
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Buidler smallVideoWidth(int SMALL_VIDEO_WIDTH) {
|
||||||
|
this.SMALL_VIDEO_WIDTH = SMALL_VIDEO_WIDTH;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param VIDEO_BITRATE 视频码率
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Buidler videoBitrate(int VIDEO_BITRATE) {
|
||||||
|
this.VIDEO_BITRATE = VIDEO_BITRATE;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Buidler goHome(boolean GO_HOME) {
|
||||||
|
this.GO_HOME = GO_HOME;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Buidler fullScreen(boolean full) {
|
||||||
|
this.FULL_SCREEN =full;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3
src/android/mobile-ffmpeg-x2.gradle
Normal file
3
src/android/mobile-ffmpeg-x2.gradle
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
dependencies {
|
||||||
|
implementation 'com.arthenica:mobile-ffmpeg-full:4.4'
|
||||||
|
}
|
7
www/capture.js
Normal file
7
www/capture.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
var exec = require('cordova/exec');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
capture(option, success, error) {
|
||||||
|
exec(success, error, 'capture-cordova-plugin', 'capture', [option]);
|
||||||
|
}
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user