Coder Social home page Coder Social logo

yzionted / pldroidcamerastreaming Goto Github PK

View Code? Open in Web Editor NEW

This project forked from pili-engineering/pldroidmediastreaming

0.0 2.0 0.0 2.28 MB

Pili Live Streaming SDK for Android Camera, H.264 / AAC hardware encoding and RTMP publishing supported.

License: Apache License 2.0

Java 100.00%

pldroidcamerastreaming's Introduction

PLDroidCameraStreaming

PLDroidCameraStreaming 是一个适用于 Android 的 RTMP 直播推流 SDK,可高度定制化和二次开发。特色是支持 Android Camera 画面捕获并进行 H.264 硬编码, 以及支持 Android 麦克风音频采样并进行 AAC 硬编码;同时,还实现了一套可供开发者选择的编码参数集合,以便灵活调节相应的分辨率和码率。借助 PLDroidCameraStreaming ,开发者可以快速构建一款类似 MeerkatPeriscope 的 Android 直播应用。

功能特性

  • 支持 MediaCodec 硬编码
  • 支持 AAC 音频编码
  • 支持 H264 视频编码
  • 内置生成安全的 RTMP 推流地址
  • 支持 RTMP 协议推流
  • 支持 ARMv7a
  • Android Min API 18
  • 支持前后置摄像头,以及动态切换
  • 支持自动对焦
  • 支持闪光灯操作
  • 支持纯音频推流,以及后台运行

内容摘要

使用方法

项目配置

releases/ 目录获取:

  • pldroid-camera-streaming-xxx.jar
  • armeabi-v7a/libpldroid_ffmpegbridge.so 并在项目中加入对应的 jar / so 文件的依赖关系,可参考 PLDroidCameraStreamingDemo 中的做法。

权限

在项目开始前,您需要在 AndroidManifest.xml 中添加如下权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />

可参考 PLDroidCameraStreamingDemo 中的做法。

示例代码

  1. 编写布局文件
<com.pili.pldroid.streaming.widget.AspectFrameLayout
    android:id="@+id/cameraPreview_afl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true" >

    <android.opengl.GLSurfaceView
        android:id="@+id/cameraPreview_surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />
</com.pili.pldroid.streaming.widget.AspectFrameLayout>
  1. 初始化 LayoutView
AspectFrameLayout afl = (AspectFrameLayout) findViewById(R.id.cameraPreview_afl);
GLSurfaceView glSurfaceView = (GLSurfaceView) findViewById(R.id.cameraPreview_surfaceView);
  1. 实例化并初始化 StreamingProfileStreamCameraStreamingSetting

streamJsonStrFromServer 是由服务端返回的一段 JSON String,该 JSON String 描述了 Stream 的结构。通常,您可以使用 Pili 服务端 SDK 的 getStream(streamId) 方法来获取一个 Stream 对象,在服务端并将该对象以 JSON String 格式输出,该输出即是 streamJsonStrFromServer 变量的内容。例如,一段 JSON 格式的 Stream 内容如下:

{
    "id": "z1.live.55920c19fb16df0cbf00af8e",
    "hub": "live",
    "title": "55910c13fb16df0cbf00af8e",
    "publishKey": "b06c7427b454762e",
    "publishSecurity": "dynamic",
    "hosts" : {
        "publish" : {
            "rtmp"   : "xxx.pub.z1.pili.qiniup.com"
        },
        "play"    : {
            "hls"    : "xxx.hls1.z1.pili.qiniucdn.com",
            "rtmp"   : "xxx.live1.z1.pili.qiniucdn.com"
        }
    }
    // ...
}

然后根据 streamJsonStrFromServer 构造 JSONObject 类型的对象 streamJson

/*
*
* You should get the streamJson from your server, maybe like this:
*
* Step 1: Get streamJsonStrFromServer from server
* URL url = new URL(yourURL);
* URLConnection conn = url.openConnection();
*
* HttpURLConnection httpConn = (HttpURLConnection) conn;
* httpConn.setAllowUserInteraction(false);
* httpConn.setInstanceFollowRedirects(true);
* httpConn.setRequestMethod("GET");
* httpConn.connect();
*
* InputStream is = httpConn.getInputStream();
* streamJsonStrFromServer = convertInputStreamToString(is);
*
* Step 2: Instantiate streamJson object
* JSONObject streamJson = new JSONObject(streamJsonStrFromServer);
*
*
* Then you can use streamJson to instantiate stream object
* Stream stream = new Stream(streamJson);
*
* */
String streamJsonStrFromServer = "stream json string from your server";

JSONObject streamJson = null;
try {
    streamJson = new JSONObject(streamJsonStrFromServer);
} catch (JSONException e) {
    e.printStackTrace();
}
        
Stream stream = new Stream(streamJson);

StreamingProfile profile = new StreamingProfile();
profile.setVideoQuality(StreamingProfile.VIDEO_QUALITY_MEDIUM1)
       .setAudioQuality(StreamingProfile.AUDIO_QUALITY_HIGH2)
       .setStream(stream);

CameraStreamingSetting setting = new CameraStreamingSetting();
setting.setCameraId(Camera.CameraInfo.CAMERA_FACING_BACK)
       .setContinuousFocusModeEnabled(true)
       .setStreamingProfile(profile)
       .setCameraPrvSizeLevel(CameraStreamingSetting.PREVIEW_SIZE_LEVEL.MEDIUM)
       .setCameraPrvSizeRatio(CameraStreamingSetting.PREVIEW_SIZE_RATIO.RATIO_4_3);
  • SDK 预定义的 Video Quality 列表:
public static final int VIDEO_QUALITY_LOW1;
public static final int VIDEO_QUALITY_LOW2;
public static final int VIDEO_QUALITY_LOW3;

public static final int VIDEO_QUALITY_MEDIUM1;
public static final int VIDEO_QUALITY_MEDIUM2;
public static final int VIDEO_QUALITY_MEDIUM3;

public static final int VIDEO_QUALITY_HIGH1;
public static final int VIDEO_QUALITY_HIGH2;
public static final int VIDEO_QUALITY_HIGH3;
  • SDK 预定义的 Audio Quality 列表:
public static final int AUDIO_QUALITY_LOW1;
public static final int AUDIO_QUALITY_LOW2;

public static final int AUDIO_QUALITY_MEDIUM1;
public static final int AUDIO_QUALITY_MEDIUM2;

public static final int AUDIO_QUALITY_HIGH1;
public static final int AUDIO_QUALITY_HIGH2;
  • Video Quality 配置表
Level Fps Video Bitrate(Kbps)
VIDEO_QUALITY_LOW1 12 150
VIDEO_QUALITY_LOW2 15 264
VIDEO_QUALITY_LOW3 15 350
VIDEO_QUALITY_MEDIUM1 30 512
VIDEO_QUALITY_MEDIUM2 30 800
VIDEO_QUALITY_MEDIUM3 30 1000
VIDEO_QUALITY_HIGH1 30 1200
VIDEO_QUALITY_HIGH2 30 1500
VIDEO_QUALITY_HIGH3 30 2000
  • Audio Quality 配置表
Level Audio Bitrate(Kbps) Audio Sample Rate(Hz)
AUDIO_QUALITY_LOW1 18 44100
AUDIO_QUALITY_LOW2 24 44100
AUDIO_QUALITY_MEDIUM1 32 44100
AUDIO_QUALITY_MEDIUM2 48 44100
AUDIO_QUALITY_HIGH1 96 44100
AUDIO_QUALITY_HIGH2 128 44100

若设置一个未被 SDK 支持的 quality,将会得到 IllegalArgumentException("Cannot support the quality:" + quality) 异常。

  • SDK 预定义的 preivew size level 列表:
CameraStreamingSetting.PREVIEW_SIZE_LEVEL.SMALL
CameraStreamingSetting.PREVIEW_SIZE_LEVEL.MEDIUM
CameraStreamingSetting.PREVIEW_SIZE_LEVEL.LARGE
  • SDK 预定义的 preview size ratio 列表:
CameraStreamingSetting.PREVIEW_SIZE_RATIO.RATIO_4_3
CameraStreamingSetting.PREVIEW_SIZE_RATIO.RATIO_16_9

SDK 会根据您设置的 ratio 、 level 从系统支持的 preview size 列表中找到最佳的 size

若缺少上述步骤,SDK 默认使用如下设置:

Camera Id      : Camera.CameraInfo.CAMERA_FACING_BACK
Publish Url    : Environment.getExternalStorageDirectory().getAbsolutePath() + "/pldroid-recording.mp4"
Audio Quality  : StreamingProfile.AUDIO_QUALITY_LOW1
Video Quality  : StreamingProfile.VIDEO_QUALITY_LOW1
Prv Size Level : MEDIUM
Prv Size Ratio : RATIO_16_9
  1. 实例化并初始化核心类 CameraStreamingManager
  • Camera Streaming
mCameraStreamingManager = new CameraStreamingManager(this, afl, glSurfaceView);
mCameraStreamingManager.onPrepare(setting);
mCameraStreamingManager.setStreamingStateListener(this);
  • Pure Audio Streaming
mCameraStreamingManager = new CameraStreamingManager(this);
mCameraStreamingManager.onPrepare(setting);
mCameraStreamingManager.setStreamingStateListener(this);

您需要实现 StreamingStateListener,以便通过回调函数 onStateChanged 接收如下消息:

  • STATE.PREPARING
  • STATE.READY
  • STATE.CONNECTING
  • STATE.STREAMING
  • STATE.SHUTDOWN
  • STATE.IOERROR
  • STATE.NETBLOCKING
  • STATE.CAMERA_SWITCHED
  • STATE.TORCH_INFO
  • STATE.CONNECTION_TIMEOUT

您需要注意的是,onStateChanged 回调函数可能被非 UI 线程调用,可参考 CameraStreamingActivity

  1. 开始推流
// should be invoked after getting STATE.READY message
mCameraStreamingManager.startStreaming();
  1. 停止推流
mCameraStreamingManager.stopStreaming();
  1. CameraStreamingManager 另外几个重要的状态周期函数 onResume()onPause()onDestory()

如果 CameraStreamingManager 存在于某一个 Activity 中,建议在 Activity 的 onResume()onPause()onDestory() 中分别进行调用 CameraStreamingManager 的周期函数,即:

@Override
protected void onResume() {
  super.onResume();
  mCameraStreamingManager.onResume();
}

@Override
protected void onPause() {
  super.onPause();
  mCameraStreamingManager.onPause();
  getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
    
@Override
protected void onDestroy() {
  super.onDestroy();
  mCameraStreamingManager.onDestroy();
}

纯音频推流支持后台运行,你只需要控制好 onPause()onDestory() 周期函数即可。

  1. setNativeLoggingEnabled(enabled)

当 enabled 设置为 true ,SDK Native 层的 log 将会被打开;当设置为 false,SDK Native 层的 log 将会被关闭。默认处于打开状态。

mCameraStreamingManager.setNativeLoggingEnabled(false);

依赖库

  • FFMPEG

版本历史

  • 1.2.3 (Release Notes)

    • 发布 pldroid-camera-streaming-1.2.3.jar
    • 新增 Audio quality 和 Video quality 配置项,可自由组合音视频码率参数
    • 新增 Video quality 设置接口 setVideoQuality
    • 新增 Audio quality 设置接口 setAudioQuality
    • 优化 jar 包,减少约 30% 体积
  • 1.2.2 (Release Notes)

    • 发布 pldroid-camera-streaming-1.2.2.jar
    • 更新 libpldroid_ffmpegbridge.so
    • 修复概率性的 crash 问题
    • 添加 STATE.CONNECTION_TIMEOUT 状态
    • 修复部分机型因连接错误而导致屏幕 Hang 住
    • 在 UI 层对点击事件加入保护逻辑,避免快速点击导致应用 crash
  • 1.2.1 (Release Notes)

    • 发布 pldroid-camera-streaming-1.2.1.jar
    • 更新 libpldroid_ffmpegbridge.so
    • 优化内存问题,修复 OOM 异常
    • 优化 Quality 配置
    • 添加 setNativeLoggingEnabled() 接口
  • 1.2.0 (Release Notes)

    • 发布 pldroid-camera-streaming-1.2.0.jar
    • 更新 libpldroid_ffmpegbridge.so
    • 更新 Stream 设置接口:setStream(stream)
    • 添加 Camera 切换接口:switchCamera
    • 修复 Android L crash 问题
    • 添加 Camera 切换状态:STATE.CAMERA_SWITCHED
    • 添加 Torch 是否支持状态:STATE.TORCH_INFO
    • 更新状态回调接口:onStateChanged(state, extra)
    • 修复特殊操作的概率性 crash 问题
    • 修复部分机型 turnLightOnturnLightOff 接口无效问题
    • 修复部分机型点击 Home 按键 crash 问题
    • 修复部分机型因 PREVIEW_SIZE_LEVEL 导致 crash 问题
    • 添加 Camera 切换操作演示代码
    • 更新 Torch 组件显示逻辑
  • 1.1.0 (Release Notes)

    • 发布 pldroid-camera-streaming-1.1.0.jar
    • 更新 libpldroid_ffmpegbridge.so
    • 优化 ffmpegbridge 模块,降低 libpldroid_ffmpegbridge.so 文件大小
    • 添加纯音频推流支持:添加纯音频推流 CameraStreamingManager(Context ctx) 构造函数
    • 纯音频推流支持后台运行
    • 添加 preview size 设定接口:setCameraPrvSizeLevelsetCameraPrvSizeRatio
    • 添加 torch 操作接口: turnLightOnturnLightOff
    • 添加控制连续自动对焦的接口:setContinuousFocusModeEnabled
    • 废弃 setCameraPreviewSize 接口
    • 修复部分机型因 preivew size 不支持而导致的 crash 问题
    • 添加 AudioStreamingActivityStreamingBaseActivity,用来演示纯音频推流
    • 添加 torch 操作演示代码
  • 1.0.2 (Release Notes)

    • 发布 pldroid-camera-streaming-1.0.2.jar
    • 修复无 StreamingStateListener 情况下的 Crash 问题
    • 修复正常启动后无 READY 消息返回问题
    • 更新 Stream 定义,并与服务端保持一致
    • 增加相机正常启动后即开始推流功能
  • 1.0.1 (Release Notes)

    • 发布 pldroid-camera-streaming-1.0.1.jar
    • 更新 Stream 类结构
    • 更新 Stream 的构造方式
  • 1.0.0 (Release Notes)

    • 发布 PLDroidCameraStreaming v1.0.0

pldroidcamerastreaming's People

Contributors

jpxiong avatar why404 avatar

Watchers

James Cloos avatar Yzion Ted avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.