【OSS排查方案-4】OSS+RTMP推流的JAVA方法
背景:目前有很多直播愛好者使用的是 OSS + RTMP 做的推流直播,其中不乏一些企業級別應用,由於 OSS 作為推流的接收略微有一些複雜,故單獨開篇講一下。其實不建議使用 OSS+RTMP 做直播推流,因為功能性相比專業的阿里雲直播幾乎為 0 ,而且效能上並不好。建議大家使用單獨的直播服務。
首先:
看下官網對於 OSS 推流的過程定義
- 只能使用RTMP推流的方式,不支援拉流。
- 必須包含視訊流,且視訊流格式為H264。
- 音訊流是可選的,並且只支援AAC格式,其他格式的音訊流會被丟棄。
- 轉儲只支援HLS協議。
- 一個LiveChannel同時只能有一個客戶端向其推流。
RTMP 的推流格式:
rtmp://your-bucket.oss-cn-hangzhou.aliyuncs.com/live/test-channel
rtmp://your-bucket.oss-cn-hangzhou.aliyuncs.com/live/test-channel
- live 等同於 RTMP 的 APP 掛載點
- test-channel 等同於 RTMP 的 stream name
RTMP URL 推流簽名:
- rtmp://${bucket}.${host}/live/${channel}?OSSAccessKeyId=xxx&Expires=yyy&Signature=zzz&${params}
- 推流前 LiveChannel有兩種Status:enabled和disabled,使用者可以使用本介面在兩種Status之間進行切換。處於disabled狀態時,OSS會禁止使用者向該LiveChannel進行推流操作;如果有使用者正在向該LiveChannel推流,那麼推流的客戶端會被強制斷開(可能會有10s左右的延遲)
我們現在用 java 的 SDK 演示一下如上的推理過程,在跑 SDK 之前,需要先搭建好一套本地的 eclipse 環境,如下是我用的 eclipse,如果有沒搭建請網上搜尋一下 eclpse 的搭建方式(之前需要安裝 JDK 且配置環境變數)
- Eclipse 版本:Version: Neon.3 Release (4.6.3)
- JDK 版本:jdk1.8.0_144
- OSS:公開讀(為了驗證推流功能是否正常,我們用公開讀的方式快速測試)
我們採用主函式入口的方式,例項化其他類進行呼叫,這樣方便類的拆分,不用都集合在主函式中。
主函式 domain,例項化 OSSClient 物件傳入到 RtmpTest 類中測試。
所有的 jar 都會通過官方的 maven 解決的依賴關係,https://help.aliyun.com/document_detail/32009.html?spm=5176.doc32008.6.672.HR4Dbr
package javasdk;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import com.aliyun.oss.OSSClient;
public class domain {
public static void main( String[] args ) throws ParseException, FileNotFoundException
{
System.out.println( "Hello World!" );
String accessid = "AK";
String secretkey = "SK";
String objectpath = "C://Users//hanli.zyb//Desktop//running.png";
String bucket = "bucket";
String object = "running";
String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
// OSS + rtmp 推流
String bucketName = "ali-hangzhou";
RtmpTest pushoss = new RtmpTest();
OSSClient ossClient = new OSSClient(endpoint, AK, SK);
pushoss.testCreateLiveChannel(bucketName,ossClient);
}
}
RtmpTest
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package javasdk;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import junit.framework.Assert;
import org.junit.Ignore;
import org.junit.Test;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSErrorCode;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.utils.DateUtil;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateLiveChannelRequest;
import com.aliyun.oss.model.CreateLiveChannelResult;
import com.aliyun.oss.model.ListLiveChannelsRequest;
import com.aliyun.oss.model.LiveChannel;
import com.aliyun.oss.model.LiveChannelInfo;
import com.aliyun.oss.model.LiveChannelListing;
import com.aliyun.oss.model.LiveChannelStat;
import com.aliyun.oss.model.LiveChannelStatus;
import com.aliyun.oss.model.LiveChannelTarget;
import com.aliyun.oss.model.LiveRecord;
import com.aliyun.oss.model.PushflowStatus;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
/**
* Test rtmp
*/
public class RtmpTest {
String bucketName = "bucket";
final String liveChannel = "stream name";
@Test
public void testCreateLiveChannelDefault(String bucketname,OSSClient ossClient) {
try {
CreateLiveChannelRequest createLiveChannelRequest = new CreateLiveChannelRequest(
bucketName, liveChannel);
CreateLiveChannelResult createLiveChannelResult = ossClient.createLiveChannel(createLiveChannelRequest);
LiveChannelInfo liveChannelInfo = ossClient.getLiveChannelInfo(bucketName, liveChannel);
ossClient.deleteLiveChannel(bucketName, liveChannel);
} catch (Exception e) {
Assert.fail(e.getMessage());
}
}
@Test
public void testCreateLiveChannel(String bucketname,OSSClient ossClient) {
final String liveChannel = "normal-create-live-channel";
final String liveChannelDesc = "my test live channel";
try {
LiveChannelTarget target = new LiveChannelTarget("HLS", 100, 99, "myplaylist.m3u8");
CreateLiveChannelRequest createLiveChannelRequest = new CreateLiveChannelRequest(
bucketName, liveChannel, liveChannelDesc, LiveChannelStatus.Enabled, target);
CreateLiveChannelResult createLiveChannelResult = ossClient.createLiveChannel(createLiveChannelRequest);
System.out.println(createLiveChannelResult.getPublishUrls());
/*Assert.assertEquals(createLiveChannelResult.getPublishUrls().size(), 1);
Assert.assertTrue(createLiveChannelResult.getPublishUrls().get(0).startsWith("rtmp://"));
Assert.assertTrue(createLiveChannelResult.getPublishUrls().get(0).endsWith("live/" + liveChannel));
Assert.assertEquals(createLiveChannelResult.getPlayUrls().size(), 1);
Assert.assertTrue(createLiveChannelResult.getPlayUrls().get(0).startsWith("http://"));
Assert.assertTrue(createLiveChannelResult.getPlayUrls().get(0).endsWith(liveChannel + "/myplaylist.m3u8"));*/
/* LiveChannelInfo liveChannelInfo = ossClient.getLiveChannelInfo(bucketName, liveChannel);
Assert.assertEquals(liveChannelInfo.getDescription(), liveChannelDesc);
Assert.assertEquals(liveChannelInfo.getStatus(), LiveChannelStatus.Disabled);
Assert.assertEquals(liveChannelInfo.getTarget().getType(), "HLS");
Assert.assertEquals(liveChannelInfo.getTarget().getFragDuration(), 100);
Assert.assertEquals(liveChannelInfo.getTarget().getFragCount(), 99);
Assert.assertEquals(liveChannelInfo.getTarget().getPlaylistName(), "myplaylist.m3u8");*/
// ossClient.deleteLiveChannel(bucketName, liveChannel);
} catch (Exception e) {
Assert.fail(e.getMessage());
}
}
}
其中我們最關注的是 testCreateLiveChannel 類,建立了推流地址,其中引數 LiveChannelStatus.enable 是要讓推流變為可用狀態。
public void testCreateLiveChannel(String bucketname,OSSClient ossClient) {
final String liveChannel = "normal-create-live-channel";
final String liveChannelDesc = "my test live channel";
try {
LiveChannelTarget target = new LiveChannelTarget("HLS", 100, 99, "myplaylist.m3u8");
CreateLiveChannelRequest createLiveChannelRequest = new CreateLiveChannelRequest(
bucketName, liveChannel, liveChannelDesc, LiveChannelStatus.Enabled, target);
CreateLiveChannelResult createLiveChannelResult = ossClient.createLiveChannel(createLiveChannelRequest);
System.out.println(createLiveChannelResult.getPublishUrls());
/*Assert.assertEquals(createLiveChannelResult.getPublishUrls().size(), 1);
Assert.assertTrue(createLiveChannelResult.getPublishUrls().get(0).startsWith("rtmp://"));
Assert.assertTrue(createLiveChannelResult.getPublishUrls().get(0).endsWith("live/" + liveChannel));
Assert.assertEquals(createLiveChannelResult.getPlayUrls().size(), 1);
Assert.assertTrue(createLiveChannelResult.getPlayUrls().get(0).startsWith("http://"));
Assert.assertTrue(createLiveChannelResult.getPlayUrls().get(0).endsWith(liveChannel + "/myplaylist.m3u8"));*/
// ossClient.deleteLiveChannel(bucketName, liveChannel);
} catch (Exception e) {
Assert.fail(e.getMessage());
}
}
running 主函式,列印出推流地址。
rtmp://hangzhou.oss-cn-hangzhou.aliyuncs.com/live/normal-create-live-channel
請網友們自己親自搭建環境動手實際測試,有問題可隨時留言帖子。
相關文章
- AndroidRTMP直播推流方案選擇Android
- OSS物件儲存的全球加速方案物件
- JavaCV推流實戰(MP4檔案)Java
- [擴充套件推薦]Aliyun-oss-laravel —— Laravel最好的OSS Storage擴充套件套件Laravel
- java專案cpu佔用高排查方法(chatgpt)JavaChatGPT
- webshell應急排查方案Webshell
- java:佈局方法(流佈局)Java
- 直播平臺搭建,Java 記憶體溢位的排查方法Java記憶體溢位
- Java的流Java
- 實戰排查|為什麼遮擋推流攝像頭,會導致播放綠屏?
- java問題排查Java
- Java cpu 高排查Java
- 子賬戶及STS臨時賬戶呼叫OSS的常見問題及排查
- Java 不可變集合 Stream流以及方法引用Java
- java中遍歷Map的4種方法Java
- 流衝突解決方案——流
- Java的IO流Java
- Java 的 流操作Java
- 伺服器大流量的排查方法伺服器
- 安防監控影片匯聚方案EasyCVR平臺呼叫裝置錄影不返回影片流的原因排查VR
- 排查Java的記憶體問題Java記憶體
- java Activiti 工作流引擎 SSM 框架模組設計方案JavaSSM框架
- java 工作流表單設計器 設計方案Java
- Java-Stream流方法學習及總結Java
- JAVA死鎖排查-效能測試問題排查思路Java
- 【Java中遍歷Map物件的4種方法】Java物件
- Java多執行緒推薦使用的停止方法和暫停方法Java執行緒
- Java流Java
- 伺服器網路不通的排查方法伺服器
- ECSAPI中Signature錯誤的排查方法API
- linux系統很卡的基本排查方法Linux
- 使用OSS搭建私有云內網yum倉庫的方法內網
- 把HTML轉成PDF的4個方案及實現方法HTML
- 利用greys排查java問題Java
- java 位元組流檔案複製方法總結Java
- Java之獲取隨機數的4種方法Java隨機
- Java中如何遍歷Map物件的4種方法Java物件
- Java實現檔案拷貝的4種方法.Java