
相机采集:摄像头、麦克风采集数据样本(YUV/PCM),相机功能设置
画面预览:将图像渲染到画布
编辑模块:添加美颜、滤镜、动态贴纸等
录制:视频多段录制、回删等 素材模块
为了方便您快速集成,我们将特效相机逻辑封装在进阶使用类(PipeMediator) 中,您只需控制采集时机即可.
| 接口文件 | 功能 | 
|---|---|
| PipeMediator | 进阶使用类 | 
| AudioConvert | 音频转换 | 
| PreviewManager | 画面预览 | 
| RecordManager | 视频录制 | 
| BeautyManager | 美颜特效 | 
| RenderPipe | 核心渲染管道 | 
示例
// PipeMediator.java
    /**
     * @param buffer NV21数据
     * @param bufferWidth NV21数据宽度
     * @param bufferHeight NV21数据高度
     * @param stride 每行数据长度
     * @return
     */
    public Image onFrameAvailable(ByteBuffer buffer, int bufferWidth, int bufferHeight, int stride){
        if (!isReady) return null;
        synchronized (PipeMediator.class) {
            //1. 通过ImageConvert 将Android默认的OES纹理转换为可处理的Texture2D纹理
            Image in = mImageConvert.onFrameAvailable(buffer,bufferWidth,bufferHeight,stride);
            //2. 通过BeautyManager进行美颜处理
            Image out = mBeautyManager.processFrame(in);
            //3. 将处理后的Image显示到View上
            if (mCurrentPreviewRect == null) {
                mPreviewManager.updateImage(out);
            } else {
                mPreviewManager.updateImage(out, mCurrentPreviewRect);
            }
            //4. 需要录制的情况下 将处理后的Image对象送入RecordManager进行文件输出
            if (mRecordManager != null) {
                long recordPos = System.currentTimeMillis();
                mRecordManager.sendImage(out, recordPos);
            }
            in.release();
            out.release();
            return out;
        }
    }
// PipeMediator.java
    /**
     * @param context Context 对象
     * @param parent 渲染View父布局
     * @param aspect 默认渲染尺寸比例
     * @return Init结果 不为0时 说明参数存在错误
     */
    public Pair<Boolean,Integer> requestInit(Context context, ViewGroup parent, SizeF aspect);
    /**
     * @param renderWidth 渲染画面宽度 默认值为720
     */
    public void setRenderWidth(int renderWidth);
    /**
     * @param aspect 更新渲染画面比例
     */
    public void updateAspect(SizeF aspect);
     /**
     * @param rectF 实际渲染区域 默认计算方式为fitin
     */
    public void changedRect(@Nullable RectF rectF);
    /**
     * 开始录制视频
     * 
     * @param outputPath 视频输出绝对路径
     * @param width 视频输出宽度
     * @param height 视频输出高度
     * @param watermark 水印图片
     * @param watermarkPos 水印位置 // 0 : tl, 1 : tr, 2 : bl, 3 : br
     */
    public void startRecord(String outputPath, int width, int height, @Nullable Bitmap watermark, int watermarkPos);
/**
     * @return 获取美颜属性管理类
     */
    public BeautyManager getBeautyManager()
摄像头、麦克风采集数据样本(SurfaceTexture/PCM)。包括摄像头切换、闪光灯、画面对焦、分辨率及码率设置等
| 接口文件 | 功能 | 
|---|---|
| TuCameraImpl | 相机采集功能 | 
| TuSurfaceTextureHolder | 相机数据回调 | 
示例
TuSurfaceTextureHolder mCameraHolder = new TuSurfaceTextureHolder() {
        @Override
        public SurfaceTexture requestSurfaceTexture() {
            // 获取相机绘制纹理
            mSurfaceTexture = mPipeMediator.getSurfaceTexture();
            return mSurfaceTexture;
        }
        @Override
        public void setInputRotation(ImageOrientation previewOrientation) {
            // 获取相机方向
            mPreviewOrientation = previewOrientation;
            mPipeMediator.setInputRotation(previewOrientation.getDegree(),previewOrientation.isMirrored());
        }
        @Override
        public void setInputSize(TuSdkSize previewOptimizeSize) {
            // 获取相机尺寸
            mInputSize = previewOptimizeSize;
            mRecordView.setDisplaySize(mInputSize.width,mInputSize.height);
            mPipeMediator.setInputSize(mInputSize.width,mInputSize.height);
        }
        @Override
        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
            if (!mPipeMediator.isReady()){
                //第一帧回调的时候 初始化PipeMediator对象
                TuSdkSize size = ViewSize.create(mCameraView);
                mCurrentRatio = TuCameraAspectRatio.of(size.width,size.height);
                mPipeMediator.requestInit(getBaseContext(),mCameraView,new SizeF(mCurrentRatio.getX(),mCurrentRatio.getY()));
                mRecordView.initFilterPipe(mPipeMediator.getBeautyManager());
                mCurrentRenderSize = TuSdkSize.create((int) PROCESS_WIDTH, (int) (PROCESS_WIDTH / mCurrentRatio.getX() * mCurrentRatio.getY()));
            }
            //通知PipeMediator从相机绘制纹理中获取当前画面
            Image image = mPipeMediator.onFrameAvailable();
            if (!isRecording){
                //如果录制未开启 资源的释放需要在这里进行
                image.release();
            }
        }
    };
mCamera = new TuCameraImpl();
// 设置相机纹理回调
mCamera.setSurfaceHolder(mCameraHolder);
// 设置是否相机是否默认使用最大尺寸采集
mCamera.setFullFrame(false);
// 相机预初始化
if (!mCamera.prepare()) return;
// 设置预览尺寸
mCamera.cameraSize().setPreviewSize(PREVIEW_SIZE);
// 设置相机默认采集方向
mCamera.cameraBuilder().setDefaultFacing(CameraConfigs.CameraFacing.Front);
// 设置相机预览方向       mCamera.cameraOrient().setDisplayRotation(getWindowManager().getDefaultDisplay().getRotation());
// 设置相机纹理输出方向
mCamera.cameraOrient().setOutputImageOrientation(InterfaceOrientation.Portrait);
// 设置相机状态回调
mCamera.setCameraListener(new TuCamera.TuCameraListener() {
            @Override
            public void onStatusChanged(CameraConfigs.CameraState status, TuCamera camera) {
                if (status == START){
                    mRecordView.setExposure();
                }
            }
        });
调整相机参数
//TuCamera.java
/** 相机接口 */
public interface TuCamera {
    /** 相机相机参数处理接口 */
    TuCameraParams cameraParams();
    /** 相机方向处理接口 */
    TuCameraOrient cameraOrient();
    /** 相机聚焦接口 */
    TuCameraFocus cameraFocus();
    /** 相机长宽接口 */
    TuCameraSize cameraSize();
    /** 相机拍摄接口 */
    TuCameraShot cameraShot();
    /** 准备初始化相机 [是否初始化成功] */
    boolean prepare();
    /** 切换前后摄像头 [是否启动摄像头成功] */
    boolean rotateCamera();
    /** 相机前后位置 */
    CameraFacing getFacing();
    /** 开始预览  [是否启动摄像头成功] */
    boolean startPreview();
    /** 开始预览  [是否启动摄像头成功] */
    boolean startPreview(CameraFacing facing);
    /** Pause camera preview [是否成功暂定预览] */
    boolean pausePreview();
    /** Resume camera preview  [是否成功恢复预览] */
    boolean resumePreview();
    /** 停止预览 */
    void stopPreview();
    /** 拍摄照片 [是否开始拍摄] */
    boolean shotPhoto();
    /** 释放资源 */
    void release();
}
/** 相机参数处理接口 */
public interface TuCameraParams {
    /** 配置相机参数 @param builder 相机创建接口 */
    void configure(TuCameraBuilder builder);
    /** 相机状态改变 */
    void changeStatus(CameraState status);
    /** 当前镜头是否有闪光灯 */
    boolean canSupportFlash();
    /** 闪关灯模式 @see # {@link org.lasque.tusdkpulse.core.utils.hardware.CameraConfigs.CameraFlash} */
    CameraFlash getFlashMode();
    /** 设置闪光灯模式 **/
    void setFlashMode(CameraFlash flashMode);
    /** 是否需要统一配置参数 (默认true, 取消三星默认降噪,锐化) */
    void setUnifiedParameters(boolean unifiedParameters);
    /** 设置抗条带 */
    void setAntibandingMode(CameraAntibanding antiBandingMode);
    /** 设置白平衡 */
    void setWhiteBalance(CameraWhiteBalance whiteBalance);
    /** 设置曝光补偿级数 **/
    void setExposureCompensation(int ev);
    /** 处理相机焦距变化 [是否放大焦距]*/
    void setZoom(int scale, boolean isZoomIn);
    /**
     * 获取当前设备支持的最小曝光级数
     *
     * @return 最小曝光级数
     */
    public int getMinExposureCompensation();
    /**
     * 获取当前设备支持的最大曝光级数
     *
     * @return 最大曝光级数
     */
    public int getMaxExposureCompensation();
    /**
     * 获取当前曝光级数
     *
     * @return 当前曝光级数
     */
    public int getCurrentExposureCompensation();
    /**
     * 获取当前设别曝光补偿Step
     *
     * @return 当前曝光补偿Step
     */
    public float getExposureCompensationStep();
}
将采集的数据样本转换成 Image。
| 接口文件 | 功能 | 
|---|---|
| ImageConvert | 样本转换 | 
| Image | 图像结构 | 
// ImageConvert.java
// 通知纹理更新
public Image onFrameAvailable();
// 获取纹理
public SurfaceTexture getSurfaceTexture();
// 获取实际渲染尺寸
public TuSdkSize getRenderSize();
像素格式、采样分辨率
// ImageConvert.java
// 设置渲染比例
public boolean setAspect(double w,double h);
//更新比例
public void updateAspect(double w,double h);
// 设置输入尺寸与方向
public void setInputSize(int width,int height,ImageOrientation cameraOrientation);
// 设置渲染宽度
public void setRenderWidth(int renderWidth);
将采集的数据样本添加变速、变调、混音等。
| 接口文件 | 功能 | 
|---|---|
| AudioConvert | 音频转换 | 
| AudioConvert.AudioItem | 音频数据 | 
// AudioConvert.java
public static class AudioItem {
        // PCM数据
        public byte[] buffer;
        // 数据长度
        public int length;
        // 时间戳
        public long time;
        public AudioItem(byte[] buffer, int length, long time);
    }
// 送入转换数据
public int sendAudioData(AudioItem item);
// 接收数据
public AudioItem receiveAudioData() throws InterruptedException;
// AudioConvert.java
/**
 * @param channels 声道数
 * @param sampleRate 音频采样率
 * @return 初始化状态
 */
public boolean requestInit(int channels, int sampleRate);
/**
 * @param path 混音文件路径 
 * @param startPos 混音文件开始播放位置
 */
public void initAudioMixer(String path, Long startPos);
/**
* 重置混音器
*/
public void resetAudioMixer(); 
/**
* 开启音频处理
*/
public void startAudioConvert();
/**
* 结束音频处理
*/
public void stopAudioConvert();
/**
* 开始混音文件播放
*/
public void startAudioPlayer();
/**
* 结束混音文件播放
*/
public void stopAudioPlayer();
将Image渲染到画布
| 接口文件 | 功能 | 
|---|---|
| PreviewManager | 画面预览 | 
| Image | 图像 | 
// PreviewManager.java
/**
* @param context 上下文对象
* @param parent 父控件
* @return 初始化状态
*/
public Pair<Boolean,Integer> requestInit(Context context, ViewGroup parent);
/**
* 更新预览画面
* @param image 纹理资源
*/
public void updateImage(Image image);
/**
* 更新预览画面
* @param image 纹理资源
* @param rectF 渲染区域
*/
public void updateImage(Image image, RectF rectF);
画面比例、背景颜色、拍照/截图
// PreviewManager.java
/**
* 设置背景颜色
* @param color 画布背景颜色
*/
public void setBackgroundColor(int color);
在预览、视频录制的过程中,您可以给画面设置各种特效。
| 接口文件 | 功能 | 
|---|---|
| Beauty | 美颜特效接口 | 
| BeautyManager | 美颜特效实现 | 
| Image | 图像 | 
// BeautyManager.java    
/**
     * @param renderPipe 渲染队列
     * @return 初始化状态
     */
    public boolean requestInit(RenderPipe renderPipe);
    /**
     * 图像处理
     * @param in 输入纹理
     * @return 输出纹理
     */
    public Image processFrame(final Image in);
// Beauty.java    
public interface Beauty {
    /**
     * 美肤模式
     */
    public static enum BeautySkinMode {
        None(""),
        /**
         * 精准美肤
         */
        SkinNatural,
        /**
         * 极致美肤
         */
        SkinMoist,
        /**
         * 自然美肤
         */
        Beauty;
    }
    /**
     * 美妆-口红-口红样式
     */
    public enum BeautyLipstickStyle {
        /**
         * 雾面
         */
        Matte(0),
        /**
         * 水润
         */
        Moisturizing(2),
        /**
         * 滋润
         */
        Moisturize(1);
        public static BeautyLipstickStyle getStyleFromValue;
    }
    /**
     * @param beautyStyle 美肤模式
     */
    void setBeautyStyle(BeautySkinMode beautyStyle);
    /**
     * @param level 磨皮级别
     */
    void setSmoothLevel(float level);
    /**
     * @param level 美白级别
     */
    void setWhiteningLevel(float level);
    /**
     * 仅限 精准/极致 美肤模式使用
     * @param level 红润级别
     */
    void setRuddyLevel(float level);
    /**
     * 仅限 自然美肤模式使用
     * @param level 锐化级别
     */
    void setSharpenLevel(float level);
    /**
     * @return 当前是否开启了微整形
     */
    boolean hasPlastic();
    /**
     * @param level 设置大眼级别 [0-1]
     */
    void setEyeEnlargeLevel(float level);
    /**
     * @param level 设置瘦脸级别 [0-1]
     */
    void setCheekThinLevel(float level);
    /**
     * @param level 设置窄脸级别 [0-1]
     */
    void setCheekNarrowLevel(float level);
    /**
     * @param level 设置小脸级别 [0-1]
     */
    void setFaceSmallLevel(float level);
    /**
     * @param level 设置瘦鼻级别 [0 - 1]
     */
    void setNoseWidthLevel(float level);
    /**
     * @param level 设置长鼻级别 [0 - 1]
     */
    void setNoseHeightLevel(float level);
    /**
     * @param level 设置嘴型级别 [-1 - 1]
     */
    void setMouthWidthLevel(float level);
    /**
     * @param level 设置唇厚级别 [-1 - 1]
     */
    void setLipsThicknessLevel(float level);
    /**
     * @param level 设置缩人中界别 [-1 - 1]
     */
    void setPhilterumThicknessLevel(float level);
    /**
     * @param level 设置细眉级别 [-1 - 1]
     */
    void setBrowThicknessLevel(float level);
    /**
     * @param level 设置眉高级别 [-1 - 1]
     */
    void setBrowHeightLevel(float level);
    /**
     * @param level 设置下巴(拉伸或收缩)级别 [-1 - 1]
     */
    void setChinThicknessLevel(float level);
    /**
     * @param level 设置下颌骨级别 [0 - 1]
     */
    void setCheekLowBoneNarrowLevel(float level);
    /**
     * @param level 设置眼角级别 [0 - 1]
     */
    void setEyeAngleLevel(float level);
    /**
     * @param level 设置开内眼角级别 [0 - 1]
     */
    void setEyeInnerConerLevel(float level);
    /**
     * @param level 设置开外眼角级别 [0 - 1]
     */
    void setEyeOuterConerLevel(float level);
    /**
     * @param level 设置眼距级别 [-1 - 1]
     */
    void setEyeDistanceLevel(float level);
    /**
     * @param level 设置眼移动级别 [-1 - 1]
     */
    void setEyeHeightLevel(float level);
    /**
     * @param level 设置发际线级别 [-1 - 1]
     */
    void setForeheadHeightLevel(float level);
    /**
     * @param level 设置瘦颧骨级别 [-1 - 1]
     */
    void setCheekBoneNarrowLevel(float level);
    /**
     * @param level 这是双眼皮级别 [0 - 1]
     */
    void setEyelidLevel(float level);
    /**
     * @param level 设置卧蚕级别 [0 - 1]
     */
    void setEyemazingLevel(float level);
    /**
     * @param level 设置白牙级别 [0 - 1]
     */
    void setWhitenTeethLevel(float level);
    /**
     * @param level 设置亮眼级别 [0 - 1]
     */
    void setEyeDetailLevel(float level);
    /**
     * @param level 设置祛黑眼圈级别 [0 - 1]
     */
    void setRemovePouchLevel(float level);
    /**
     * @param level 设置祛法令纹级别 [0 - 1]
     */
    void setRemoveWrinklesLevel(float level);
    /**
     * @param enable 设置开启美妆-口红
     */
    void setLipEnable(boolean enable);
    /**
     * @param style 设置口红样式 水润 滋润 雾面
     */
    void setLipStyle(BeautyLipstickStyle style);
    /**
     * @param opacity 设置口红透明度 [0 - 1]
     */
    void setLipOpacity(float opacity);
    /**
     * @param color 设置口红颜色
     */
    void setLipColor(int color);
    /**
     * @param enable 设置开启美妆-腮红
     */
    void setBlushEnable(boolean enable);
    /**
     * @param opacity 设置腮红透明度 [0 - 1]
     */
    void setBlushOpacity(float opacity);
    /**
     * @param stickerId 设置腮红ID
     */
    void setBlushStickerId(long stickerId);
    /**
     * @param enable 设置开启美妆-眉毛
     */
    void setBrowEnable(boolean enable);
    /**
     * @param opacity 设置眉毛透明度 [0 - 1]
     */
    void setBrowOpacity(float opacity);
    /**
     * @param stickerId 设置眉毛ID
     */
    void setBrowStickerId(long stickerId);
    /**
     * @param enable 设置开启美妆-眼影
     */
    void setEyeshadowEnable(boolean enable);
    /**
     * @param opacity 设置眼影透明度 [0 - 1]
     */
    void setEyeshadowOpacity(float opacity);
    /**
     * @param stickerId 设置眼影ID
     */
    void setEyeshadowStickerId(long stickerId);
    /**
     * @param enable 设置开启美妆-眼线
     */
    void setEyelineEnable(boolean enable);
    /**
     * @param opacity 设置眼线透明度 [0 - 1]
     */
    void setEyelineOpacity(float opacity);
    /**
     * @param stickerId 设置眼线ID
     */
    void setEyelineStickerId(long stickerId);
    /**
     * @param enable 设置开启美妆-睫毛
     */
    void setEyelashEnable(boolean enable);
    /**
     * @param opacity 设置睫毛透明度 [0 - 1]
     */
    void setEyelashOpacity(float opacity);
    /**
     * @param stickerId 设置睫毛ID
     */
    void setEyelashStickerId(long stickerId);
    /**
     * @param enable 设置开启美妆-修容
     */
    void setFacialEnable(boolean enable);
    /**
     * @param opacity 设置修容透明度 [0 - 1]
     */
    void setFacialOpacity(float opacity);
    /**
     * @param stickerId 设置修容ID
     */
    void setFacialStickerId(long stickerId);
    /**
     * 设置滤镜
     * @param filterCode 滤镜代号
     */
    void setFilter(String filterCode);
    /**
     * @param strength 滤镜强度 [0 - 1]
     */
    void setFilterStrength(float strength);
    /**
     * 设置人脸动态贴纸
     * @param stickerId 贴纸ID
     */
    void setDynamicSticker(long stickerId);
    /**
     * @return 当前是否使用了人脸动态贴纸
     */
    boolean hasDynamicSticker();
    /**
     * 设置人脸哈哈镜
     * @param code 哈哈镜代号
     */
    void setMonsterFace(String code);
    /**
     * @return 当前是否使用了人脸哈哈镜
     */
    boolean hasMonsterFace();
    /**
     * 设置视频合拍
     * @param videoRect 合拍素材渲染区域 [0,0,1,1]
     * @param cameraRect 相机画面渲染区域 [0,0,1,1]
     * @param videoPath 合拍素材路径
     */
    void setJoiner(RectF videoRect,RectF cameraRect,String videoPath);
    /**
     * 取消合拍
     */
    void deleteJoiner();
    /**
     * 更新合拍素材以及相机渲染区域
     * @param videoRect 合拍素材渲染区域 [0,0,1,1]
     * @param cameraRect 相机画面渲染区域 [0,0,1,1]
     */
    void updateJoiner(RectF videoRect,RectF cameraRect);
    /**
     * @return 当前是否应用了合拍功能
     */
    boolean hasJoiner();
    /**
     * 合拍素材跳转
     * @param ts 视频跳转位置
     * @return 是否跳转成功
     */
    boolean joinerSeek(long ts);
    /**
     * 调节合拍视频播放速度
     * @param videoStretch 播放速度
     */
    void updateVideoStretch(double videoStretch);
    /**
     * 设置渲染宽度
     * @param size 渲染宽度
     */
    void setRenderSize(TuSdkSize size);
    /**
     * 设置合拍视频开始播放位置
     * @param ts 
     */
    void updateJoinerPlayerStartPos(long ts);
    /**
     * 设置合拍视频播放状态
     * @param isPlaying 是否开始播放
     */
    void setJoinerPlayerState(boolean isPlaying);
}
视频分段录制、变速录制、视频合成保存等
| 接口文件 | 功能 | 
|---|---|
| RecordManager | 视频录制 | 
| Image | 图像 | 
| VideoFragmentItem | 视频录制片段 | 
// RecordManager.java    
public static class VideoFragmentItem{
        /**
         * 片段保存路径
         */
        public String path;
        /**
         * 片段长度
         */
        public long fragmentDuration;
    }
    public static interface RecordListener{
        /**
         * 进度回调
         * @param progress 比例 0~1
         * @param ts 时间戳
         */
        void onProgress(float progress,long ts);
        /**
         * 录制超时回调
         */
        void onRecordTimeOut();
        /**
         * 启动录制回调
         */
        void onRecordStart();
        /**
         * 录制暂停回调
         */
        void onRecordPause();
        /**
         * 录制停止回调
         */
        void onRecordStop();
    }
    /**
     * 创建视频录制工具
     *
     * @param outputPath 最终输出路径
     * @param width 视频宽度
     * @param height 视频高度
     * @param channels 音频声道数
     * @param sampleRate 音频采样率
     * @param watermark 水印图片
     * @param watermarkPos 水印位置
     * @param glContext 纹理采集环境上下文
     * @return 创建状态 -1 参数异常 0 成功
     */
    public Pair<Boolean,Integer> newExporter(String outputPath, int width, int height, int channels, int sampleRate, @Nullable Bitmap watermark, int watermarkPos, GLContext glContext);
    /**
     * @return 开始视频录制
     */
    public boolean startExporter();
    /**
     * 重置录制工具状态
     */
    public void resetExporter();
    /**
     * @return 暂停录制
     */
    public boolean pauseExporter();
    /**
     * @return 停止录制
     */
    public boolean stopExporter();
    /**
     * 输入视频
     * @param image 视频帧
     * @param ts 时间戳
     */
    public void sendImage(Image image,long ts);
    /**
     * 输入音频 最大可处理4096长度的数据
     * @param buffer 音频数据
     * @param length 数据长度
     * @param ts 时间戳
     */
    public void sendAudio(byte[] buffer,int length,long ts);
录制速度、声音设置、设置水印
// RecordManager.java     
/**
     * @param listener 录制监听
     */
    public void setRecordListener(RecordListener listener);
    /**
     * @param durationMS 录制最大时间
     */
    public void setMaxRecordDuration(long durationMS);
    /**
     * @param stretch 更新视频速度
     */
    public void updateStretch(double stretch);
// RecordManager.java     
/**
     * @return 弹出最后一段录制片段
     */
    public VideoFragmentItem popFragment();
    /**
     * @return 获取当前录制片段数量
     */
    public int getFragmentSize();
    /**
     * @return 获取当前录制时长
     */
    public long getCurrentRecordDuration();
    /**
     * 保存视频 目前适配到Android11
     * @param input 输入路径
     * @param output 输出路径 可以为公共区域
     */
    public void saveVideo(String input,String output);