集成Android SDK,实现简单的推流功能。
预计部署时间:20分钟
级别:初级
相关产品:视频直播
受众: 通用
本次测试使用环境:1. Android Studio Bumblebee | 2021.1.1 Patch 2
2. macOS 12.3
3. Gradle Plugin Version 7.1.2
4. Gradle Version 7.4.1
5. Gradle JDK 17
jcenter() maven { url "https://artifact.bytedance.com/repository/Volcengine/" }
android { defaultConfig { ndk { //设置 SO 库架构,支持 armv7a 和 arm64 架构。 abiFilters 'armeabi-v7a', 'arm64-v8a' } // APPLOG_SCHEME 为必填参数,空缺会造成编译失败。 // online 表示直播场景。 manifestPlaceholders.put("APPLOG_SCHEME", "online") } } //添加 AppLog 在线集成地址。用于 SDK 日志上报。 implementation 'com.bytedance.applog:RangersAppLog-Lite-cn:6.8.0' implementation 'com.bytedanceapi:ttsdk-ttlivepush_rtc:1.26.2.7'
android.enableJetifier=true
<!-- 使用权限 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
package com.quit.xxxx; import static com.pandora.common.Constants.APPLog.APP_REGION_CHINA; import android.app.Application; import android.content.Context; import android.util.Log; import com.pandora.common.env.Env; import com.pandora.common.env.config.Config; import com.pandora.common.utils.TimeUtil; import com.pandora.common.utils.Times; import com.pandora.ttlicense2.License; import com.pandora.ttlicense2.LicenseManager; public class APP extends Application { public static final String TAG = "pushDemo"; private static Context context; /* 获取全局上下文 */ public static Context getContext() { return context; } @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); Env.openAppLog(true); Env.init(new Config.Builder() .setAppName("com.quit.test") .setAppID("330309") .setAppRegion(APP_REGION_CHINA) .setApplicationContext(context) .setAppVersion("1.0") .setAppChannel("push-demo") .setLicenseUri("assets:///License/l-100871-ch-live-a-330309.lic") .build()); //添加 License 鉴权。 LicenseManager.init(getApplicationContext()); //开启 License 模块 logcat 输出。建议排查问题时开启,发包时关闭。 LicenseManager.turnOnLogcat(true); //配置授权文件 URI,推流 SDK 支持从 assets 文件夹中读取授权。 String assetsLicenseUri = "assets:///xxxxxx.lic"; //添加授权文件。将 license URI 添加到 LicenseManager。 LicenseManager.getInstance().addLicense(assetsLicenseUri, null); //License 信息获取。 License license = LicenseManager.getInstance().getLicense("100871"); if (license != null) { StringBuilder builder = new StringBuilder(); builder.append("License id:" + license.getId()).append("\n") .append("License package:" + license.getPackageName()).append("\n") .append("License test:" + license.getType()).append("\n") .append("License version:" + license.getVersion()).append("\n"); if (license.getModules() != null) { String names = ""; for (License.Module module : license.getModules()) { names = "module name:" + module.getName() + ", start time:" + TimeUtil.format(module.getStartTime(), Times.YYYY_MM_DD_KK_MM_SS) + ", expire time:" + TimeUtil.format(module.getExpireTime(), Times.YYYY_MM_DD_KK_MM_SS) + "\n"; builder.append("License modules:" + names); } } } } }
<application android:name=".APP" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" ......
<Button android:id="@+id/start_button" android:layout_width="match_parent" android:layout_height="wrap_content" tools:ignore="MissingConstraints" /> <TextureView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" />
package com.quit.xxxx; import static com.ss.avframework.livestreamv2.LiveStreamBuilder.VIDEO_CAPTURE_DEVICE_CAM_FRONT; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import android.util.Log; import android.view.TextureView; import android.view.View; import android.widget.Button; import com.pandora.ttsdk.newapi.LiveCoreBuilder; import com.pandora.ttsdk.newapi.LiveCoreEngine; import com.ss.avframework.livestreamv2.ILiveStream; import com.ss.avframework.livestreamv2.LiveStreamBuilder; import com.ss.avframework.livestreamv2.core.LiveCore; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { public LiveCoreBuilder builder; public TextureView surfaceView; public LiveCore mliveCore; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); checkPermission(1001); initTTSDK(); Button start_button = findViewById(R.id.start_button); start_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mliveCore.start("rtmp://lsspush.yzyzyang.xyz/live/spting-test"); } }); } public void initTTSDK() { builder = new LiveCoreBuilder(); //视频参数配置。 //采集帧率,默认值为 30。 builder.setVideoCaptureFps(30); //视频采集宽度,默认值为 720。 builder.setVideoCaptureWidth(1080); //视频采集高度,默认值为 1280。 builder. setVideoCaptureHeight(1920); //启动前置/后置摄像头,默认值为 VIDEO_CAPTURE_DEVICE_CAM_FRONE。 //VIDEO_CAPTURE_DEVICE_CAM_FRONE 表示前置摄像头;VIDEO_CAPTURE_DEVICE_CAM_BACK 表示后置摄像头。 builder.setVideoCaptureDevice(VIDEO_CAPTURE_DEVICE_CAM_FRONT); //开启硬件加速,默认值为 true。 builder.setEnableVideoEncodeAccelera(true); //推流宽度,默认值为 540。 builder.setVideoWidth(720); //推流高度,默认值为 960。 builder.setVideoHeight(1280); //推流帧率,默认值为 25。 builder.setVideoFps(30); //编码等级,默认值为 VIDEO_ENCODER_PROFILE_HIGH builder.setVideoProfile(LiveStreamBuilder.VIDEO_ENCODER_PROFILE_HIGH); //码率,默认值为 800*1000。 builder.setVideoBitrate( 800*1000); //配置码率控制策略、最大码率和最小码率。 //码率控制策略默认值为 BITRATE_ADAPT_STRATEGY_NORMAL builder.setBitrateAdaptStrategy(LiveStreamBuilder.BITRATE_ADAPT_STRATEGY_NORMAL); //最大码率默认为设置码率的 5/3。 builder.setVideoMaxBitrate( 800*1000 * 5 / 3); //最小码率默认为设置码率的 2/5。 builder.setVideoMinBitrate( 800*1000 * 2 / 5); //音频参数配置,采集设备。 builder.setAudioCaptureDevice(LiveStreamBuilder.AUDIO_CAPTURE_DEVICE_ADM); //采集采样率,默认值为 44100。 builder.setAudioCaptureSampleHZ(44100); //采集声道数,默认值为 1,1 表示单声道,2 表示双声道。 builder.setAudioCaptureChannel(1); //创建推流引擎。 LiveCoreEngine liveCoreEngine = builder.getLiveCoreEngine(); mliveCore = liveCoreEngine.getLiveCore(); mliveCore.enableMirror(true,true); surfaceView = (TextureView) findViewById(R.id.surfaceView); surfaceView.setVisibility(View.VISIBLE); mliveCore.setDisplay(surfaceView); //开始视频采集。 mliveCore.startVideoCapture(); mliveCore.startAudioCapture(); mliveCore.setErrorListener(new ILiveStream.ILiveStreamErrorListener() { @Override public void onError(int i, int i1, Exception e) { Log.e("onERROR","ERROR",e); } }); mliveCore.setDataListener(new ILiveStream.ILiveStreamDataListener() { @Override public void onData(int i, int i1, int i2) { Log.i("onData","surfaceCreated"+i+"i1"+i1); } }); //必填配置,设置推流消息监听。 mliveCore.setInfoListener(new ILiveStream.ILiveStreamInfoListener() { @Override public void onInfo(int i, int i1, int i2) { Log.i("onInfo","onInfo"+i+"i1"+i1); } }); } //获取权限 private boolean checkPermission(int request) { String permissions[] = new String[]{ Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_PHONE_STATE, Manifest.permission.MODIFY_AUDIO_SETTINGS, Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; List<String> permissionList = new ArrayList<>(); for (String permission : permissions) { boolean granted = ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED; if (granted) continue; permissionList.add(permission); } if (permissionList.isEmpty()) return true; String permissionsToGrant[] = new String[permissionList.size()]; permissionList.toArray(permissionsToGrant); ActivityCompat.requestPermissions(this, permissionsToGrant, request); return false; } }