package com.yixia.camera.demo.ui.record.views;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import com.yixia.camera.demo.common.CommonIntentExtra;
import com.yixia.camera.demo.log.Logger;
import com.yixia.camera.demo.po.POThemeSingle;
import com.yixia.camera.demo.preference.PreferenceKeys;
import com.yixia.camera.demo.preference.PreferenceUtils;
import com.yixia.camera.demo.ui.record.helper.RecorderHelper;
import com.yixia.camera.model.MediaObject;
import com.yixia.camera.util.FileUtils;
import com.yixia.camera.util.StringUtils;
import com.yixia.videoeditor.adapter.UtilityAdapter;
/**
* MV主题预览
*
* @author tangjun
*
*/
public class ThemeSufaceView extends SurfaceView implements Callback {
/** 循环 */
private static final int HANDLER_MESSAGE_LOOP = 0;
/** 进度检测 */
private static final int HANDLER_MESSAGE_PROGRESS = 1;
/** 画布 */
private SurfaceHolder mSurfaceHolder;
/** 视频存储对象 */
private MediaObject mMediaObject;
/** 当前主题 */
private POThemeSingle mCurrentTheme;
/** 视频播放完回调 */
private OnComplateListener mOnComplateListener;
/** 视频音乐 */
private String mMusicPath;
/** 输出路径 */
private String mOutputPath;
/** 输入 */
private String mInputPath;
/** MV滤镜路径,滤镜公共目录 */
private String mMVPath, mFilterCommonPath, mFilterPath, mWatermarkPath, mWatermarkBlendmode;
/** 片尾动画路径 */
private String mEndPath;
/** 矩阵参数 */
private String mOpengMainmat;
/** 特定贴图信息 */
private String mPoster;
/** 画布是否准备 */
private boolean mSurfaceCreated;
/** 是否正在播放 */
private boolean mIsPlaying, mIsPause;
/** 是否需要初始化Filter */
private boolean mNeedInit;
/** 是否导入图片 */
private boolean mImportImage;
/** 随机数因子 */
private long mRandomFactor;
/** 片尾的宽高 */
private int mEndWidth, mEndHeight;
/** 录制模式 */
private int mRecordMode;
/** 变速 */
private float mSpeed = 1F;
/** 主题静音、原声静音 */
private boolean mThemeMute, mOrgiMute;
public ThemeSufaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ThemeSufaceView(Context context) {
super(context);
init();
}
public void reset() {
mFilterPath = "";
mWatermarkPath = "";
mWatermarkBlendmode = "";
mSpeed = 1F;
mThemeMute = false;
//mOrgiMute = false;
mPoster = "";
}
public void setPoster(String path) {
this.mPoster = path;
}
public void setSpeed(float speed) {
this.mSpeed = speed;
}
/** 设置主题静音 */
public void setThemeMute(boolean mute) {
this.mThemeMute = mute;
}
/** 设置原声静音 */
public void setOrgiMute(boolean mute) {
this.mOrgiMute = mute;
}
/** 初始化 */
private void init() {
getHolder().addCallback(this);
getHolder().setFixedSize(480, 480);
mRandomFactor = System.currentTimeMillis() / 1000;
}
public void setOnComplateListener(OnComplateListener l) {
this.mOnComplateListener = l;
}
/** 从Intent获取视频相关的参数 */
public void setIntent(Intent intent) {
if (intent != null) {
mImportImage = intent.getBooleanExtra(CommonIntentExtra.EXTRA_MEDIA_IMPORT_IMAGE, false);
boolean mImportVideo = intent.getBooleanExtra(CommonIntentExtra.EXTRA_MEDIA_IMPORT_VIDEO, false);
// mRecordMode = intent.getIntExtra("recordMode", -1);
//
// //后置摄像头
// if (mRecordMode == VideoRecorderActivity.RECORD_MODE_SYSTEM) {
// int cameraId = intent.getIntExtra("cameraId", Camera.CameraInfo.CAMERA_FACING_BACK);
// //系统录制需要翻转
// if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
// //后置摄像头
// mOpengMainmat = "mainmat= * mat2(0.0, 0.75, -1.0, 0.0) + vec2(0.0, 1.0); ";
// } else if (cameraId == Camera.CameraInfo.CAMERA_FACING_FRONT) {
// //前置摄像头
// mOpengMainmat = "mainmat= * mat2(0.0, -0.75, -1.0, 0.0) + vec2(1.0, 1.0); ";
// }
// }
}
}
/** 设置视频音乐 */
public void setMusicPath(String path) {
this.mMusicPath = path;
}
public String getMusicPath() {
return mMusicPath;
}
/** 设置视频存储信息 */
public void setMediaObject(MediaObject obj) {
this.mMediaObject = obj;
}
/** 传递当前主题信息 */
public void setTheme(POThemeSingle theme) {
this.mCurrentTheme = theme;
}
/** 设置mp4路径 */
public void setOutputPath(String output) {
this.mOutputPath = output;
}
/** 设置输入源 */
public void setInputPath(String input) {
this.mInputPath = input;
}
/** MV滤镜路径 */
public void setMVPath(String path) {
this.mMVPath = path;
}
/** 设置高级编辑-滤镜 */
public void setFilterPath(String path) {
this.mFilterPath = path;
}
/** 设置高级编辑-水印 */
public void setWatermarkPath(String path, String blendmode) {
this.mWatermarkPath = path;
this.mWatermarkBlendmode = blendmode;
}
/** MV滤镜公共路径 */
public void setFilterCommomPath(String path) {
this.mFilterCommonPath = path;
}
/** 设置片尾动画路径 */
public void setVideoEndPath(String path) {
this.mEndPath = path;
this.mEndWidth = PreferenceUtils.getInt(PreferenceKeys.THEME_LOGO_AUTHOR_WIDTH, 0);
this.mEndHeight = PreferenceUtils.getInt(PreferenceKeys.THEME_LOGO_AUTHOR_HEIGHT, 0);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mSurfaceCreated = true;
mIsPlaying = true;
mSurfaceHolder = holder;
if (mNeedInit)
initFilter();
Logger.e("[ThemeSurfaceView]surfaceCreated...");
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mSurfaceHolder = holder;
Logger.e("[ThemeSurfaceView]surfaceChanged...");
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mSurfaceCreated = false;
mIsPlaying = false;
mSurfaceHolder = null;
UtilityAdapter.FilterParserFree();
Logger.e("[ThemeSurfaceView]surfaceDestroyed...");
}
/**
* 开始转码
*
* @param outYuv 合并渲染输出一个yuv文件
* @param outPcm 合并渲染输出一个pcm文件
* @return
*/
public boolean startEncoding() {
UtilityAdapter.FilterParserInit(getSetting(true), null);
return true;
}
/** 初始化 */
public void initFilter() {
if (mSurfaceCreated && mSurfaceHolder != null) {
mIsPlaying = true;
mIsPause = false;
mNeedInit = false;
UtilityAdapter.FilterParserFree();
//预览
UtilityAdapter.FilterParserInit(getSetting(false), mSurfaceHolder.getSurface());
} else {
mNeedInit = true;
}
}
/** 继续播放 */
public void start() {
if (mSurfaceCreated) {
mIsPlaying = true;
mIsPause = false;
UtilityAdapter.FilterParserPause(false);
}
}
/** 暂停 */
public void pause() {
if (mSurfaceCreated) {
mIsPlaying = false;
mIsPause = true;
UtilityAdapter.FilterParserPause(true);
}
}
/** 是否正在播放 */
public boolean isPlaying() {
return mIsPlaying;
}
private Handler mVideoHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
int progress;
switch (msg.what) {
case HANDLER_MESSAGE_LOOP:
progress = UtilityAdapter.FilterParserInfo(UtilityAdapter.FILTERINFO_PROGRESS);
if (progress == 100) {
if (mOnComplateListener != null)
mOnComplateListener.onComplate();
// initFilter();
// sendMessageDelayed(mVideoHandler.obtainMessage(HANDLER_MESSAGE_LOOP, msg.arg1, msg.arg2), msg.arg2);
} else {
clearMessages();
mVideoHandler.sendEmptyMessage(HANDLER_MESSAGE_PROGRESS);
}
break;
case HANDLER_MESSAGE_PROGRESS:
progress = UtilityAdapter.FilterParserInfo(UtilityAdapter.FILTERINFO_PROGRESS);
if (progress > 0) {
int delayMillis = UtilityAdapter.FilterParserInfo(UtilityAdapter.FILTERINFO_TOTALMS);//进度
int startTime = delayMillis - (int) (delayMillis * (progress / 100F));
mVideoHandler.removeMessages(HANDLER_MESSAGE_LOOP);
mVideoHandler.sendMessageDelayed(mVideoHandler.obtainMessage(HANDLER_MESSAGE_LOOP, 0, delayMillis), startTime);
} else {
sendEmptyMessageDelayed(HANDLER_MESSAGE_PROGRESS, 500);//没有取到进度,继续取
}
break;
default:
break;
}
super.handleMessage(msg);
}
};
/** 暂停并且清除定时任务 */
public void pauseClearDelayed() {
pause();
clearMessages();
}
/** 区域内循环播放 */
public void loopDelayed() {
if (mIsPause)
start();
else
initFilter();
clearMessages();
mVideoHandler.sendEmptyMessage(HANDLER_MESSAGE_PROGRESS);
}
private void clearMessages() {
if (mVideoHandler.hasMessages(HANDLER_MESSAGE_LOOP))
mVideoHandler.removeMessages(HANDLER_MESSAGE_LOOP);
if (mVideoHandler.hasMessages(HANDLER_MESSAGE_PROGRESS))
mVideoHandler.removeMessages(HANDLER_MESSAGE_PROGRESS);
}
/** 释放底层库 */
public void release() {
mIsPause = false;
mIsPlaying = false;
UtilityAdapter.FilterParserFree();
}
/** 获取底层设置参数 */
private String getSetting(boolean output) {
StringBuilder settings = new StringBuilder();
if (mMediaObject != null) {
//设置特效目录
settings.append("filterpath=");
settings.append(mMVPath);
settings.append("; ");
//设置公共目录,共用片尾,字体,音乐等
settings.append("commonpath=");
settings.append(mFilterCommonPath);
settings.append("; ");
if (!mThemeMute) {
//设置音频 //"sourcemusic=-f s16le -ar 44100 -ac 1 -i \"" + path + "/musicorg.pcm\"; "
if (StringUtils.isNotEmpty(mMusicPath)) {
settings.append("sourcemusic=-i \"");
settings.append(mMusicPath);
settings.append("\"; ");
}
}
//水印
if (FileUtils.checkFile(mWatermarkPath)) {
settings.append("watermark=-i \"");
settings.append(mWatermarkPath);
settings.append("\"; ");
if (StringUtils.isNotEmpty(mWatermarkBlendmode)) {
settings.append("blendmode=");
settings.append(mWatermarkBlendmode);
settings.append("; ");
}
}
//滤镜
if (FileUtils.checkFile(mFilterPath)) {
settings.append("filter=-i \"");
settings.append(mFilterPath);
settings.append("\"; ");
}
//贴图
if (FileUtils.checkFile(mPoster)) {
settings.append("poster=-i \"");
settings.append(mPoster);
settings.append("\"; ");
}
//变速 变速的好了,speed=2.0; 加速1倍, speed=0.5; 减速一倍
if (mSpeed < 0.9F || mSpeed > 1.1F) {//0.5、0.75、1.5、2.0
settings.append("speed=");
settings.append(mSpeed);
settings.append("; ");
}
//设置视频时长
settings.append(String.format("length=%.2f; ", (mMediaObject.getDuration() / 1000F)));
//设置输入视频文件
// if (mImportImage) {
// settings.append("inputv=");
// } else {
settings.append("inputva=");
// }
settings.append(mInputPath);
settings.append("; ");
//静音
if (mThemeMute && mOrgiMute) {
settings.append("mute=3; ");//禁音原音+主题音
} else if (mThemeMute) {
settings.append("mute=2; ");//mute=2 音乐
} else if (mOrgiMute) {
settings.append("mute=1; ");///mute=1 原音
}
//矩阵参数,暂时无用
if (StringUtils.isNotEmpty(mOpengMainmat)) {
settings.append(mOpengMainmat);
}
// //设置输入视频文件
// settings.append("inputa=");
// settings.append(mMediaObject.getConcatPCM().replace("concat:", ""));
// settings.append("; ");
//设置片段时长
if (mMediaObject.getMedaParts() != null) {
final int count = mMediaObject.getMedaParts().size();
if (count > 1) {
int duration = mMediaObject.getMedaParts().get(0).duration;
for (int i = 1; i < count && i < 3; i++) {
MediaObject.MediaPart part = mMediaObject.getMedaParts().get(i);
if (part != null) {
settings.append("seg");
settings.append(i);
settings.append("ts=");
settings.append(String.format("%.2f", duration / 1000f));
settings.append(" ");
duration += part.duration;
settings.append(String.format("%.2f", duration / 1000f));
settings.append("; ");
}
}
//如果带有第二段分段,传入第二段时间
//"seg1ts=3.0 6.0; " +
//如果带有第三段分段,传入第三段时间
//"seg2ts=3.0 6.0; " +
}
}
//设置影片导演
settings.append("sourceauthor=-f rawvideo -r 15 -s ");
settings.append(mEndWidth);
settings.append("x");
settings.append(mEndHeight);
settings.append(" -pix_fmt rgba -i \"zip:");
settings.append(mEndPath);
settings.append("\"; ");
//设置影片导演图片宽度
settings.append("authorsizew=");
settings.append(mEndWidth);
settings.append("; ");
//设置影片导演图片高度
settings.append("authorsizeh=");
settings.append(mEndHeight);
settings.append("; ");
//设置码率
settings.append("bitrate=");
settings.append(RecorderHelper.getVideoBitrate());//mMediaObject.mVideoBitrate
settings.append("; ");
}
//随机因子
settings.append("randomfactor=");
settings.append(mRandomFactor);
settings.append("; ");
if (output) {
settings.append("outputv=\"");
settings.append(mOutputPath);
settings.append("\"; ");
}
return settings.toString();
//return String.format("filterpath=%s; inputv=%s; inputa=%s; length=%.2f; author=%s;authorsizew=%d; authorsizeh=%d", mFilterPath, mYuvPath, mPcmPath, (mDuration / 1000F), mEndPath, mEndWidth, mEndHeight);
}
public static interface OnComplateListener {
/** 播放完成 */
public void onComplate();
}
}