音视频学习 (十一) Android 端实现 rtmp 推流

本文详细介绍了在Android端如何实现rtmp推流,包括摄像头的闪光灯操作、预览控制,以及音频编码的软编和硬编方法。在软编部分,重点讲述了libfaac的编译配置、AAC包头处理和实时编码;硬编部分则讨论了MediaCodec的使用,包括创建硬编码器、配置编码参数、编码过程和释放资源。此外,还提及了视频编码中x264的交叉编译和编码配置。
摘要由CSDN通过智能技术生成

return true;
}
}

public float cameraZoom(boolean isBig) {
if(mState != State.PREVIEW || mCameraDevice == null || mCameraData == null) {
return -1;
}
Camera.Parameters params = mCameraDevice.getParameters();
if(isBig) {
params.setZoom(Math.min(params.getZoom() + 1, params.getMaxZoom()));
} else {
params.setZoom(Math.max(params.getZoom() - 1, 0));
}
mCameraDevice.setParameters(params);
return (float) params.getZoom()/params.getMaxZoom();
}

4.7 闪光灯操作

一个摄像头可能有相应的闪光灯,也可能没有,因此在使用闪光灯功能的时候先要确认是否有相应的闪光灯。检测摄像头是否有闪光灯的代码如下:

public static boolean supportFlash(Camera camera){
Camera.Parameters params = camera.getParameters();
List flashModes = params.getSupportedFlashModes();
if(flashModes == null) {
return false;
}
for(String flashMode : flashModes) {
if(Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode)) {
return true;
}
}
return false;
}

切换闪光灯的代码如下:

public static void switchLight(Camera camera, Camera.Parameters cameraParameters) {
if (cameraParameters.getFlashMode().equals(Camera.Parameters.FLASH_MODE_OFF)) {
cameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
} else {
cameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
try {
camera.setParameters(cameraParameters);
}catch (Exception e) {
e.printStackTrace();
}
}

4.8 开始预览

当打开了摄像头,并且设置好了摄像头相关的参数后,便可以通过调用 Camera 的 startPreview() 方法开始预览。有一个需要说明,无论是 SurfaceView 还是 GLSurfaceView ,都可以设置 SurfaceHolder.Callback ,当界面开始显示的时候打开摄像头并且开始预览,当界面销毁的时候停止预览并且关闭摄像头,这样的话当程序退到后台,其他应用也能调用摄像头。

private SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(SopCastConstant.TAG, “SurfaceView destroy”);
CameraHolder.instance().stopPreview();
CameraHolder.instance().releaseCamera();
}

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(SopCastConstant.TAG, “SurfaceView created”);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d(SopCastConstant.TAG, “SurfaceView width:” + width + " height:" + height);
CameraHolder.instance().openCamera();
CameraHolder.instance().startPreview();
}
};

5. 停止预览

停止预览只需要释放掉相机资源即可:

public synchronized void releaseCamera() {
if (mState == State.PREVIEW) {
stopPreview();
}
if (mState != State.OPENED) {
return;
}
if (mCameraDevice == null) {
return;
}
mCameraDevice.release();
mCameraDevice = null;
mCameraData = null;
mState = State.INIT;
}

音频编码

AudioRecord 采集完之后需要对 PCM 数据进行实时的编码 (软编利用 libfaac 通过 NDK 交叉编译静态库、硬编使用 Android SDK MediaCodec 进行编码)。

软编

语音软编这里们用主流的编码库 libfaac 进行编码 AAC 语音格式数据。

1. 编译 libfaac
1.1 下载 libfaac

wget https://sourceforge.net/projects/faac/files/faac-src/faac-1.29/faac-1.29.9.2.tar.gz

1.2 编写交叉编译脚本

#!/bin/bash
#打包地址
PREFIX=pwd/android/armeabi-v7a
#配置NDK 环境变量
NDK_ROOT=KaTeX parse error: Expected 'EOF', got '#' at position 10: NDK_HOME #̲指定 CPU CPU=arm-…NDK_ROOT/toolchains/$CPU-4.9/prebuilt/linux-x86_64

FLAGS=“-isysroot $NDK_ROOT/sysroot -isystem KaTeX parse error: Expected group after '_' at position 54: …-androideabi -D_̲_ANDROID_API__=ANDROID_API -U_FILE_OFFSET_BITS -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,–noexecstack -Wformat -Werror=format-security -O0 -fPIC”

CROSS_COMPILE= T O O L C H A I N / b i n / a r m − l i n u x − a n d r o i d e a b i e x p o r t C C = " TOOLCHAIN/bin/arm-linux-androideabi export CC=" TOOLCHAIN/bin/armlinuxandroideabiexportCC="CROSS_COMPILE-gcc --sysroot= N D K R O O T / p l a t f o r m s / a n d r o i d − 17 / a r c h − a r m " e x p o r t C F L A G S = " NDK_ROOT/platforms/android-17/arch-arm" export CFLAGS=" NDKROOT

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值