一、申請指南
官網地址:https://www.aliyun.com/product/live
準備工作:
-
在阿里雲進行ICP備案
已在其它ISP備案但未在阿里備案的也需重新接入,我這邊資料齊全一次過大概花了7天。但這裏有一個坑,阿里備案需要備案服務號,而直播這邊不提供備案服務號,在線人工諮詢、工單諮詢後,給出的回覆(2020/03/02)是目前只能去購買一臺雲服務器ECS(我們服務器沒有部署在阿里雲平臺)。好在價格也不貴,低配200/年拿了個備案服務號。 -
OBSStudio
研發時測試推流
點擊下載: OBSStudio -
PotPlayer\VLC Media Player
研發時測試播放
點擊下載: PotPlayer
點擊下載: VLC Media Player
二、配置推流地址\播放地址
1. 進入直播控制檯,點擊域名管理,點擊添加域名(域名先需在阿里雲備案)
2. 分別添加一個推流地址與播放地址(注意兩個地址需不同)
三、配置鑑權信息
進入直播控制檯,點擊域名管理,而後分別配置推流域名和播放域名
1. 配置推流域名
a. 配置回調地址
官方說明: 推斷流回調可以進行直播流流狀態實時信息回調,及時通知用戶推流或斷流操作結果。
其中https://live.aliyunlive.com/pub爲自己服務器地址,也就是配置的推流回調地址。
樣例:
https://live.aliyunlive.com/pub? action=publish & app=xc.cdnpe.com & appname=test01 & id=test01 & ip=42.120.74.183 & node=cdnvideocenter010207116011.cm3
參數說明:
b.訪問控制
點擊同頁面訪問控制,在URL鑑權中再點擊修改配置,然後設置一個鑑權KEY。推薦32位帶大小寫參。
2. 配置播放域名
a. 配置Https
點擊HTTPS配置,上傳證書即可(如無證書,可以參考我的另外一篇文章,可以免費領取一年阿里雲的SSL證書)
b. 和推流域名同樣,配置一個播放鑑權key(儘量不要與推流域名一樣)
四、 測試播放
1. 使用地址生成器生成一個推流地址與播放地址
輸入一個AppName(Path)和StreamName(Filename),點擊生成,會得到推流地址和播放地址,分別丟如OBS和Potplayer,測試是否可以正常推拉流。(工具使用該篇文章後面講解)
2. 自己組裝推拉流地址
先看官方文檔:
例如
域名:live.test.com
AppName: app
StreamName: test
Timestamp: 1583133237 (10位秒,在時間戳的前30分鐘內,該鑑權key有效)
rand: 477b3bbc253f467b8def6711128c7bec (自定義隨機字符,官方推薦去掉-的UUID,爲進一步保證鑑權Key的安全,這裏測試後得出同一流,推流的rand和播放的rand可以不同)
uid: 0 (官方說明:暫未使用,設置成 0 即可)
鑑權Key: 123456 (注意推流和播放的鑑權Key不同,上面已有講解)
組合地址後爲:
rtmp://live.test.com/app/test?auth_key=timestamp-rand-uid-md5hash
md5hash的生成方法爲:
URI-Timestamp-rand-uid-PrivateKey(URI是用戶的請求對象相對地址,不包含參數,如:/Filename)
HashValue = md5sum(sstring)
即爲:
/app/test-1583133237-477b3bbc253f467b8def6711128c7bec-0-123456
取md5小寫 (注意小寫) = e732852bdc84dac82f055cfff833f7e1,就是PrivateKey
最後拼合地址爲:
rtmp://live.test.com/app/test?auth_key=1583133237-477b3bbc253f467b8def6711128c7bec-0-e732852bdc84dac82f055cfff833f7e1
推流和播放的生成方法相同。
五、OBSStudio和PotPlayer的使用
1. OBSStudio
打開OBSStudio,點擊文件 - 設置(或者右下角設置)-切換到[推流]選項卡,把服務改爲自定義,服務器輸入推流地址即可。
然後新增一個來源,測試的話攝像頭比較好,容易觀察和判斷細節。
最後,點擊開始推流後,左下角無錯誤提示,右下角有流量在走,即推流成功。
2. PotPlayer
確定正在推流後,打開PotPlayer,輸入播放地址即可。
六、安卓的播放簡單集成
這裏使用阿里雲提供的播放SDK:https://help.aliyun.com/document_detail/125579.html?spm=a2c4g.11186623.2.7.3b656381pv9iGi
1. 引入模塊
工程build.gradle
allprojects {
repositories {
google()
jcenter()
mavenCentral()
// 添加阿里源
maven {url 'https://maven.aliyun.com/repository/releases'}
}
}
App build.grade
dependencies {
//https://help.aliyun.com/document_detail/124711.html?spm=a2c4g.11186623.6.1079.a9ea1bc7WxDrpL
//https://maven.aliyun.com/mvn/search
implementation 'com.aliyun.sdk.android:AliyunPlayer:4.7.3-full'
implementation 'com.alivc.conan:AlivcConan:1.0.2.1'
}
2. Activity源碼
package com.itxca.test.live;
import android.graphics.Bitmap;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.aliyun.player.AliPlayer;
import com.aliyun.player.AliPlayerFactory;
import com.aliyun.player.IPlayer;
import com.aliyun.player.bean.ErrorInfo;
import com.aliyun.player.bean.InfoBean;
import com.aliyun.player.nativeclass.TrackInfo;
import com.aliyun.player.source.UrlSource;
import com.itxca.test.R;
import com.itxca.test.ui.bases.BaseActivity;
/**
* Project Name : test
* Package Name : com.itxca.test.live
* Create Time : 2020-03-02 11:05
* Create By : @author xIao
* Version : 1.0.0
**/
public class AliPlayActivity extends BaseActivity {
private SurfaceView surfaceView;
private AliPlayer aliyunVodPlayer;
@Override
public boolean isRegEventBus() {
return false;
}
@Override
protected int getLayoutId() {
return R.layout.activity_tx_play;
}
@Override
protected int getTitleBarId() {
return R.id.tb_title;
}
@Override
protected void onDestroy() {
super.onDestroy();
if (aliyunVodPlayer != null) {
aliyunVodPlayer.release();
}
}
@Override
protected void initView() {
setTitle("直播播放");
}
@Override
protected void initData() {
initPlayer();
initSourceData();
}
private void initSourceData() {
//創建VidSts
UrlSource urlSource =new UrlSource();
urlSource.setTitle("測試001");
//替換該地址爲你的播放地址
urlSource.setUri("rtmp://live.test.com/app/test?auth_key=1583119273-0-0-82d0b07300f2bd4aef2df7da0adf9798");
//設置播放源
aliyunVodPlayer.setDataSource(urlSource);
//準備播放
aliyunVodPlayer.prepare();
//播放
aliyunVodPlayer.start();
}
private void initPlayer() {
//如果播放的視頻是通過播放器SDK安全下載後的本地文件,那麼還需要設置一個加密校驗信息(建議在Application中配置一次即可):
//PrivateService.initService(getApplicationContext(), "encryptedApp.dat的本地路徑");
//創建播放器
aliyunVodPlayer = AliPlayerFactory.createAliPlayer(getApplicationContext());
//綁定view
surfaceView = findViewById(R.id.sv_live_player);
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
aliyunVodPlayer.setDisplay(holder);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
aliyunVodPlayer.redraw();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
aliyunVodPlayer.setDisplay(null);
}
});
//設置回調
aliyunVodPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
@Override
public void onCompletion() {
//播放完成事件
}
});
aliyunVodPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
@Override
public void onError(ErrorInfo errorInfo) {
//出錯事件
}
});
aliyunVodPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
@Override
public void onPrepared() {
//準備成功事件
}
});
aliyunVodPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
@Override
public void onVideoSizeChanged(int width, int height) {
//視頻分辨率變化回調
}
});
aliyunVodPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
@Override
public void onRenderingStart() {
//首幀渲染顯示事件
}
});
aliyunVodPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
@Override
public void onInfo(InfoBean infoBean) {
//其他信息的事件,type包括了:循環播放開始,緩衝位置,當前播放位置,自動播放開始等
}
});
aliyunVodPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
@Override
public void onLoadingBegin() {
//緩衝開始。
}
@Override
public void onLoadingProgress(int percent, float kbps) {
//緩衝進度
}
@Override
public void onLoadingEnd() {
//緩衝結束
}
});
aliyunVodPlayer.setOnSeekCompleteListener(new IPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete() {
//拖動結束
}
});
aliyunVodPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
@Override
public void onSubtitleShow(long id, String data) {
//顯示字幕
}
@Override
public void onSubtitleHide(long id) {
//隱藏字幕
}
});
aliyunVodPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
@Override
public void onChangedSuccess(TrackInfo trackInfo) {
//切換音視頻流或者清晰度成功
}
@Override
public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
//切換音視頻流或者清晰度失敗
}
});
aliyunVodPlayer.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
@Override
public void onStateChanged(int newState) {
//播放器狀態改變事件
}
});
aliyunVodPlayer.setOnSnapShotListener(new IPlayer.OnSnapShotListener() {
@Override
public void onSnapShot(Bitmap bm, int with, int height) {
//截圖事件
}
});
}
}
3. Layout源碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/layout_titlebar" />
<include layout="@layout/layout_state" />
<SurfaceView
android:id="@+id/sv_live_player"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
七、總結
阿里雲直播的基本集成基本上就完了,推流的話Github也有很多例子,就不再詳述了。其實播放也可以不用阿里的SDK,只要支持Rtmp、Flv或者M3U8的播放器都可以。
簡單集成會很快,在域名備案成功後1小時能把推拉流調試完成,測試直播。但是阿里的設置裏面細節其實很多,包括自動截圖、錄播、導播等,官方都有詳細介紹,跟着做就行了。
整個集成流程我耗時在沒注意推流和拉流的鑑權key不同,導致生成的流一直無法使用,各位也別在這翻車了。
原帖地址,轉載請註明:https://blog.csdn.net/hx7013/article/details/104611262