Android 音视频开发——录屏直播,6年老Android面经总结

文章介绍了如何在Android中使用MediaProjection获取屏幕录制数据,进行H264编码,并利用MediaCodec进行硬件编码,随后处理编码后的数据,最终通过Rtmpdump库将编码的H264数据推流到直播服务器的过程。
摘要由CSDN通过智能技术生成

startActivityForResult(screenRecordIntent,100);

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (requestCode == 100 && resultCode == Activity.RESULT_OK) {

//MediaProjection—>产生录屏数据

mediaProjection = mediaProjectionManager.getMediaProjection

(resultCode, data);

}

}

对数据进行 h264 编码

通过 MediaProjection 获取到的 YUV 裸数据,我们先需要对其进行 h264 编码,此时我们使用原生 MediaCodec 进行硬件编码

public void start(MediaProjection mediaProjection){

this.mediaProjection = mediaProjection;

// 配置 MediaCodec

MediaFormat mediaFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC,width,height);

// 颜色格式

mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);

mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 400_000);

mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);

// 设置触发关键帧的时间间隔为 2 s

mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 2);

// 创建编码器

try {

mediaCodec = MediaCodec.createEncoderByType(“video/avc”);

mediaCodec.configure(mediaFormat,null,null,MediaCodec.CONFIGURE_FLAG_ENCODE);

Surface surface = mediaCodec.createInputSurface();

mediaProjection.createVirtualDisplay(TAG,width,height,1, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC

,surface,null,null);

} catch (IOException e) {

e.printStackTrace();

}

start();

}

@Override

public void run() {

isLiving = true;

mediaCodec.start();

MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();

while (isLiving){

//若时间差大于 2 s,则通知编码器,生成 I 帧

if (System.currentTimeMillis() - timeStamp >= 2000){

// Bundle 通知 Dsp

Bundle msgBundle = new Bundle();

msgBundle.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME,0);

mediaCodec.setParameters(msgBundle);

timeStamp = System.currentTimeMillis();

}

// 接下来就是 MediaCodec 常规操作,获取 Buffer 可用索引,这里不需要获取输出索引,内部已经操作了

int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo,100_000);

if (outputBufferIndex >=0){

// 获取到了

ByteBuffer byteBuffer = mediaCodec.getOutputBuffer(outputBufferIndex);

byte[] outData = new byte[bufferInfo.size];

byteBuffer.get(outData);

}

}

}

Rtmp 数据包

经过上面两步,我们获得了编码好的 h264 数据,接下来封装 Rtmp

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值