1、需求
1.1 要求上传时长5分钟内,大小200m内的mp4格式视频;
1.2 上传后能支持手机和电脑的浏览器播放。
2、上传逻辑
image.png3、格式
mp4格式:H.264("video/avc")/H.265(“video/hevc”);
官方的Chrome浏览器是不支持h265格式的MP4播放;
4、转码(降低视频分辨率和比特率)
4.1 自定义录制可以控制录制时长,分辨率,码率等来生成体积很小的视频;
4.2 软件解码(ffmpeg)
优点:支持的视频格式较多,功能丰富,提供了多种受支持的编解码器和容器,并具有执行编辑操作(合并/拆分视频,合并/解复用轨道,修改帧等)的功能.
缺点:转码速度相对慢,可能会消耗大量电池和CPU。
4.3 硬件解码 (MediaCodec)
优点:支持的视频格式较少,对设备硬件有所要求,编解码器选择有限,但性能和功率效率更高;
缺点:转码速度相对快,速度与设备硬件有关。
官方示例:
|
MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat;
// 设置回调方法
codec.setCallback(new MediaCodec.Callback() {
/**
* mediacodec 存在可用输入缓冲
*/
@Override
void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
// 可通过 MediaExtractor 读取 video 或 audio 数据,然后填充数据到缓冲区
…
codec.queueInputBuffer(inputBufferId, …);
}
/**
* 输出缓冲填充完数据后
*/
@Override
void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
// 获取输出缓冲(其中包含编解码后数据)
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId);
// 处理编解码后的数据
…
// 返还输出缓冲给 codec
codec.releaseOutputBuffer(outputBufferId, …);
}
/**
* 输出格式发生变化
*/
@Override
void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
mOutputFormat = format;
}
/**
* 发生错误
*/
@Override
void onError(@NonNull MediaCodec var1, @NonNull MediaCodec.CodecException var2) {
}
});
codec.configure(format, …);
mOutputFormat = codec.getOutputFormat();
codec.start();
// wait for processing to complete
codec.stop();
codec.release();
// 两种方式创建
mMediaCodec = MediaCodec.createDecoderByType(MIME_TYPE);
mMediaCodec = MediaCodec.createByCodecName(decoderCodecName);
MediaFormat mediaFormat = new MediaFormat();
// 视频编码格式
mediaFormat.setString(MediaFormat.KEY_MIME, MIME_TYPE_VIDEO_AVC);
// 视频宽度
mediaFormat.setInteger(MediaFormat.KEY_WIDTH, width);
// 视频高度
mediaFormat.setInteger(MediaFormat.KEY_HEIGHT, height);
// 视频比特率/码率(数值越大视频质量越好)
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
// 视频关键帧间隔时间
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, keyFrameInterval);
// 视频帧率(单位时间内视频显示帧数)
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
// 可以查找设备所支持的解码器
MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
String decoderCodecName = mediaCodecList.findDecoderForFormat(mediaFormat);
说明:
1、码率:码率越大,视频文件越大;码率越小,视频文件越小
2、帧率:帧率与画面的流畅度成正比。帧率越大,画面越流畅;帧率越小,画面有卡顿感。
3、在编码的时候,保证WIDTH 与 HEIGHT两者是16的整数倍。
5、最后
第三方封装库:<u>https://github.com/linkedin/LiTr</u>
延伸阅读:https://engineering.linkedin.com/blog/2019/litr-a-lightweight-video-audio-transcoder-for-android
网友评论