创建并配置 LiveVideoCamera
对象,代码如下:
// 相机视图容器
RelativeLayout cameraView = (RelativeLayout) findViewById(R.id.lsq_cameraView);
LiveVideoCamera videoCamera = new LiveVideoCamera(this.getBaseContext(), cameraView);
// 滤镜事件代理
videoCamera.setDelegate(mVideoCameraDelegate);
// 设置视频编码器委托
videoCamera.setVideoDataDelegate(mVideoDataDelegate);
// 设置音频编码器委托
videoCamera.setAudioDataDelegate(mAudioDataDelegate);
LiveVideoCamera
的构造方法中需要传入两个参数:
Context
)RelativeLayout
)相机视图容器是一个 RelativeLayout
布局,一般在 XML 布局文件中指定,传入 LiveVideoCamera
构造方法中后,会将相机预览视图加载在该视图容器中。
获取直播相机对象之后,使用 setDelegate(TuSDKVideoCameraDelegate)
方法设置滤镜事件代理,当滤镜效果发生变化的时候会回调该代理下的 onFilterChanged(SelesOutInput selesOutInput)
方法。
获取直播相机对象后,可以对该相机的属性进行一些设置:
使用 setVideoCaptureSetting(TuSDKVideoCaptureSetting)
接口可以指定采集时的配置,
TuSDKVideoCaptureSetting
中可以对相机采集时的多项属性进行设置,包括:
facing
,相机朝向(默认: CameraFacing.Front
前置)videoSize
,输出画面尺寸,仅当 videoAVCodecType == AVCodecType.CUSTOM_CODEC
时生效(默认:TuSdkSize(320, 480)
)fps
,采集帧率(默认:24
)videoAVCodecType
,视频编码类型(默认: AVCodecType.HW_CODEC(硬编)
)imageFormatType
,输出帧数据的格式, 当 videoAVCodecType == AVCodecType.CUSTOM_CODEC
时生效,默认 ImageFormatType.NV21
其中 AVCodecType
定义如下:
/**
* 音视频编码类型
*/
public static enum AVCodecType
{
// 硬编
HW_CODEC,
// 软编
SW_CODEC,
// 自定义编码。输出帧数据,用户自定义编码
CUSTOM_CODEC
}
开启智能美颜和动态贴纸 (默认: false)。
因为性能原因,目前只能在硬编模式下才能使用动态贴纸:
this.setEnableFaceAutoBeauty(true);
开启音频采集(默认:false)
setEnableAudioCapture(true);
是否使用横屏采集(默认:竖屏)
setOutputImageOrientation(InterfaceOrientation.PortraitUpsideDown);
前置摄像头采集的内容是否需要水平镜像处理
setHorizontallyMirrorFrontFacingCamera(true);
在创建相机对象时可以使用 setVideoCaptureSetting(TuSDKVideoCaptureSetting)
接口指定采集时的配置,其中该配置类下的 videoAVCodecType
属性代表了希望获取的数据是原始帧数据还是编码后的数据(软编或硬编)。
当设置 videoAVCodecType
为 HW_CODEC
或是 SW_CODEC
类型时,SDK 会通过视频编码器委托中的回调将编码后的视频数据回传(硬编或软编),用户可以在回调接口中获取数据,如下:
/**
* 视频编码器委托
*/
private TuSDKVideoDataEncoderDelegate mVideoDataDelegate = new TuSDKVideoDataEncoderDelegate()
{
@Override
public void onVideoEncoderStarted(MediaFormat format)
{
}
@Override
public void onVideoEncoderFrameDataAvailable(long tms,ByteBuffer byteBuffer, BufferInfo bufferInfo)
{
}
};
videoCamera.setVideoDataDelegate(mVideoDataDelegate);
同时,使用下面的方式获取编码后的音频数据(硬编或软编):
/**
* 视频编码器委托
*/
private TuSDKVideoDataEncoderDelegate mVideoDataDelegate = new TuSDKVideoDataEncoderDelegate()
{
@Override
public void onVideoEncoderStarted(MediaFormat format)
{
}
@Override
public void onVideoEncoderFrameDataAvailable(long tms,ByteBuffer byteBuffer, BufferInfo bufferInfo)
{
}
};
videoCamera.setVideoDataDelegate(mVideoDataDelegate);
当设置 videoAVCodecType
为 CUSTOM_CODEC
类型时,SDK 会通过帧数据委托中的回调将原始帧数据回传,用户可以在回调接口中获取数据并自行做编码操作,如下:
/**
* 帧数据委托,videoAVCodecType == AVCodecType.CUSTOM_CODEC 时才会调用。
*
* 输出每桢的数据
*/
private TuSDKLiveVideoCameraDelegate mFrameDelegate = new TuSDKLiveVideoCameraDelegate()
{
@Override
public void onFrameDataAvailable(byte[] frameData)
{
TLog.d("Frame data ready");
// 将转换后的 frameData 用于视频编码
// 软编:编码 -> 推流
}
};
this.setFrameDelegate(mFrameDelegate);
同时用户可以通过设置 imageFormatType
的值来指定输出的帧数据的格式,如下:
TuSDKVideoCaptureSetting captureSetting = new TuSDKVideoCaptureSetting();
captureSetting.imageFormatType = ImageFormatType.NV21;
其中 ImageFormatType
定义如下:
/**
* videoAVCodecType == CUSTOM_CODEC 时输出的帧数据格式
*/
public static enum ImageFormatType
{
NV21,
YV12,
I420
}
创建并配置推流实例对象,如下:
// 配置 LiveEngine,推流之前 fps 和 videoSize 将作为 MetaData 数据发送至服务器
TuSDKLiveEngineSetting liveSettings = TuSDKLiveEngineSetting.defaultSetting();
liveSettings.fps = getVideoEncoderSetting().videoQuality.getFps();
liveSettings.videoSize = getVideoEncoderSetting().videoSize;
TuSDKLiveEngine mLiveEngine = TuSDKLiveEngine.create(liveSettings);
其中 TuSDKLiveEngineSetting
是 TuSDKLiveEngine
类的配置参数类,可以通过该类指定推流时的一些参数:
fps
,帧率videoSize
,画面尺寸adaptiveBitrateEnable
,是否开启自适应码率streamingMeterTimeGranularity
,直播流统计时长粒度,单位:毫秒,默认:3000,即每三秒统计一次streamingMessageMaxQueueLength
,推流消息队列最大长度,默认:150获取推流实例对象之后,可以通过 setEngineEventHandler(TuSDKLiveEngineEventHandler)
接口设置推流状态改变时的回调方法,如下:
mLiveEngine.setEngineEventHandler(new TuSDKLiveEngineEventHandler()
{
@Override
public void onStreamingStateChanged(StreamingState state)
{
// 流状态改变
}
@Override
public void onConnectStateChanged(ConnectState state)
{
// 连接状态改变
}
@Override
public TuSDKLiveVideoQuality settingVideoQuality()
{
// 返回当前编码器设置的视频质量
return null;
}
@Override
public boolean onRequestUpdateVideoQuality(AdapterResult arg0)
{
// 根据当前推流状态请求更新视频画质
return false;
}
});
当相机对象调用了 startRecording()
方法之后才会有数据从回调方法中返回,因此可以把启动推流的代码放在 startRecording()
方法中,如下:
String RTMPURL;
@Override
public void startRecording()
{
super.startRecording();
mLiveEngine.startStreaming(RTMPURL);
}
其中使用 startStreaming(String rtmpAddress)
方法设置推流地址并开启推流。
使用下面的方式结束推流:
@Override
public void stopRecording()
{
super.stopRecording();
mLiveEngine.stopStreaming();
}
当设置 videoAVCodecType
为 HW_CODEC
或是 SW_CODEC
类型时,编码后的音视频数据都会通过设置的回调方法返回,可以在回调方法中使用 sendFrame(TuSDKLiveRTMPData frame)
接口将数据推到服务器,如下:
/**
* 视频编码器委托
*/
private TuSDKVideoDataEncoderDelegate mVideoDataDelegate = new TuSDKVideoDataEncoderDelegate()
{
@Override
public void onVideoEncoderStarted(MediaFormat format)
{
TuSDKLiveRTMPData rtmpData = TuSDKLiveRTMPData.videoDataHeader(format);
mLiveEngine.sendFrame(rtmpData);
}
@Override
public void onVideoEncoderFrameDataAvailable(long tms,ByteBuffer byteBuffer, BufferInfo bufferInfo)
{
TuSDKLiveRTMPData rtmpData = TuSDKLiveRTMPData.videoFrameData(tms, byteBuffer, bufferInfo);
mLiveEngine.sendFrame(rtmpData);
}
};
/**
* 音频编码器委托
*/
private TuSDKAudioDataEncoderDelegate mAudioDataDelegate = new TuSDKAudioDataEncoderDelegate()
{
@Override
public void onAudioEncoderStarted(MediaFormat format) {
TuSDKLiveRTMPData rtmpData = TuSDKLiveRTMPData.audioDataHeader(format);
mLiveEngine.sendFrame(rtmpData);
}
@Override
public void onAudioEncoderFrameDataAvailable(long tms, ByteBuffer byteBuffer, BufferInfo bufferInfo) {
TuSDKLiveRTMPData rtmpData = TuSDKLiveRTMPData.audioFrameData(tms, byteBuffer, bufferInfo);
mLiveEngine.sendFrame(rtmpData);
}
};
可以在下载的资源文件中找到 lsq_tusdk_configs.json
文件,之前在控制台所打包的滤镜资源会在这个文件中显示,比如"name":"lsq_filter_VideoFair"
,则该滤镜的 filterCode 即为 VideoFair
,需注意大小写。
以 demo 为例,可以将此 filterCode 设置在 SimpleCameraActivity.java
文件的滤镜数组中,如下:
// 要支持多款滤镜,直接添加到数组即可
private String[] videoFilters = new String[]{"VideoFair"};
如果有多款滤镜,分别取得滤镜对应的 filterCode 放到上面的数组中即可。
关于滤镜更多介绍,可以参看「自定义滤镜」文档。
创建的滤镜代号数组中,每一个字符串都代表一个滤镜的 filterCode
,将数组通过 mFilterListView.setModeList(List<String>)
的方式传给 FilterListView
类,然后在 FilterCellView
类中的 bindModel()
方法中通过 filterCode
获取滤镜对应的缩略图,并将该缩略图显示在该项滤镜视图上面。
详细实现可以参考短视频 demo 中的示例。
同时用户也可以使用自己的列表来显示滤镜,并可以自定义滤镜的缩略图(替换掉对应名称的图片即可)。
在 demo 中,点击滤镜项会调用 onFilterGroupSelected()
方法,在该方法中调用 tuSDKVideoCamera.switchFilter(filterCode)
方法即可切换滤镜效果。
可以设置打开相机时默认开启滤镜效果,实现如下:
@Override
protected void onCameraStarted()
{
super.onCameraStarted();
// 开机启动美颜
switchFilter("VideoFair");
}
即重写 TuSDKLiveVideoCamera
类中的 onCameraStarted()
方法,并调用 switchFilter(String)
方法即可。
动态贴纸资源可以通过StickerLocalPackage.shared().getSmartStickerGroups()
方法获取,并返回一个 List<StickerGroup>
类型的返回值,里面包含着所有打包下载到本地的动态贴纸资源。
跟加载滤镜资源不一样,加载贴纸资源时使用的是从打包下载的资源文件中读取的贴纸缩略图,然后通过 mStickerListView.setModeList(groups)
方法将贴纸资源传给 StickerListView
类中,最后在 StickerCellView
类中的 bindModel()
方法中使用 StickerLocalPackage.shared().loadGroupThumb(StickerGroup data, ImageView posterView)
接口将贴纸缩略图绑定到对应视图上。
详细实现可以参考短视频 demo 中的示例。
同时用户也可以使用自己的列表来显示贴纸,参考 demo 中的实现。
在 demo 中,点击贴纸栏会调用 onStickerGroupSelected()
方法,在该方法中调用 showGroupSticker(StickerGroup)
方法显示传入的贴纸,使用 removeAllLiveSticker()
方法取消动态贴纸效果。
©2019-2024 TUTUCLOUD. All Rights Reserved. 杭州元凡视觉智能科技有限公司 | 浙ICP备14040447号-1 | 浙公网安备33010602001649号