全部產品
Search
文件中心

Object Storage Service:RTMP推流上傳

更新時間:Dec 19, 2024

OSS支援使用RTMP協議推送H264編碼的視頻流和AAC編碼的音頻流到OSS。推送到OSS的音視頻資料可用於點播或直播情境。本文介紹如何推送音視頻流到OSS,以及如何播放推送到OSS的音視頻資料。

使用限制

  • 只能使用RTMP推流的方式,不支援拉流。

  • 上傳的音視頻資料中必須包含視頻流,且視頻流格式為H264。

  • 上傳的音視頻資料中可選擇是否包含音頻流。若包含音頻流,則只支援AAC格式的音頻流,其他格式的音頻流會被丟棄。

  • 轉儲只支援HLS協議。

  • 一個LiveChannel同時只能有一個用戶端向其推流。

向OSS推送音視頻資料

  1. 擷取推流地址。

    使用SDK調用PutLiveChannel介面建立一個LiveChannel,並擷取對應的推流地址。

    • 如果Bucket的許可權控制(ACL)為公用讀寫(public-read-write),可直接使用擷取的推流地址進行推流。

    • 如果Bucket ACL為公用讀取(public-read)或者私人(private),則需要進行簽名操作。關於簽名的具體步驟,請參見簽名版本1

    僅Java SDK、Python SDK支援擷取推流地址。

    Java

    import com.aliyun.oss.ClientException;
    import com.aliyun.oss.OSS;
    import com.aliyun.oss.OSSClientBuilder;
    import com.aliyun.oss.OSSException;
    import com.aliyun.oss.model.*;
    import java.util.List;
    import com.aliyun.oss.common.auth.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
            // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
            EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
            // 填寫Bucket名稱,例如examplebucket。
            String bucketName = "examplebucket";
            // 填寫LiveChannel名稱。
            String liveChannelName = "yourLiveChannelName";
            // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
            String region = "cn-hangzhou";
    
            // 建立OSSClient執行個體。
            ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
            clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
            OSS ossClient = OSSClientBuilder.create()
            .endpoint(endpoint)
            .credentialsProvider(credentialsProvider)
            .clientConfiguration(clientBuilderConfiguration)
            .region(region)               
            .build();
    
            try {
                CreateLiveChannelRequest request = new CreateLiveChannelRequest(bucketName,
                        liveChannelName, "desc", LiveChannelStatus.Enabled, new LiveChannelTarget());
                CreateLiveChannelResult result = ossClient.createLiveChannel(request);
    
                // 擷取推流地址。
                List<String> publishUrls = result.getPublishUrls();
                for (String item : publishUrls) {
                    // 擷取不包含簽名資訊的推流地址。
                    System.out.println(item);
    
                    // 擷取包含簽名資訊的推流地址。
                    LiveChannelInfo liveChannelInfo = ossClient.getLiveChannelInfo(bucketName, liveChannelName);
                    // expires表示到期時間,單位為Unix時間戳記。本樣本以設定到期時間為1小時為例。
                    long expires = System.currentTimeMillis() / 1000 + 3600;
                    // playlistName表示調用createLiveChannel介面時傳入的具體名稱。如果未傳入該參數,則預設值為"playlist.m3u8"。您也可以通過調用getLiveChannelInfo介面擷取該名稱。
                    String signRtmpUrl = ossClient.generateRtmpUri(bucketName, liveChannelName, liveChannelInfo.getTarget().getPlaylistName(), expires);
                    System.out.println(signRtmpUrl);
                }
    
                // 擷取播放地址。
                List<String> playUrls = result.getPlayUrls();
                for (String item : playUrls) {
                    System.out.println(item);
                }
            } catch (OSSException oe) {
                oe.printStackTrace();
                System.out.println("Caught an OSSException, which means your request made it to OSS, "
                        + "but was rejected with an error response for some reason.");
                System.out.println("Error Message:" + oe.getErrorMessage());
                System.out.println("Error Code:" + oe.getErrorCode());
                System.out.println("Request ID:" + oe.getRequestId());
                System.out.println("Host ID:" + oe.getHostId());
            } catch (ClientException ce) {
                System.out.println("Caught an ClientException, which means the client encountered "
                        + "a serious internal problem while trying to communicate with OSS, "
                        + "such as not being able to access the network.");
                System.out.println("Error Message:" + ce.getMessage());
            } finally {
                if (ossClient != null) {
                    ossClient.shutdown();
                }
            }
        }
    }

    返回的推流地址如下:

    rtmp://examplebucket.oss-cn-hangzhou.aliyuncs.com/live/test-channel
    rtmp://examplebucket.oss-cn-hangzhou.aliyuncs.com/live/test-channel?Expires=1688542428&OSSAccessKeyId=LTAI********&Signature=VfUgZt5N%2B6Uk4C9QH%2BzrRBTO2I****&playlistName=playlist.m3u8
    http://examplebucket.oss-cn-hangzhou.aliyuncs.com/test-channel/playlist.m3u8

    Python

    # -*- coding: utf-8 -*-
    import oss2
    from oss2.credentials import EnvironmentVariableCredentialsProvider
    
    # 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
    # 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
    # 填寫儲存空間名稱,例如examplebucket。
    bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
    # 填寫LiveChannel名稱,例如test-channel。
    channel_name = "test-channel"
    channel_cfg = oss2.models.LiveChannelInfo(target = oss2.models.LiveChannelInfoTarget())
    channel = bucket.create_live_channel(channel_name, channel_cfg)
    publish_url = channel.publish_url
    # 產生RTMP推流的簽名URL,並設定到期時間為3600秒。
    signed_publish_url = bucket.sign_rtmp_url(channel_name, "playlist.m3u8", 3600)
    # 列印未簽名推流地址。
    print('publish_url='+publish_url)
    # 列印簽名推流地址。
    print('signed_publish_url='+signed_publish_url)

    返回的推流地址如下:

    publish_url=rtmp://examplebucket.oss-cn-hangzhou.aliyuncs.com/live/test-channel
    signed_publish_url=rtmp://examplebucket.oss-cn-hangzhou.aliyuncs.com/live/test-channel?playlistName=playlist.m3u8&OSSAccessKeyId=LTAI********&Expires=1688543369&Signature=eqK8z0ZTSwznP7fkELy0ckt0Iv****
  2. 使用推流地址向OSS推送音視頻資料。

    使用ffmpeg進行推流

    使用ffmpeg推送本地的視頻檔案到OSS,樣本如下:

    ffmpeg -i 1.flv -c copy -f flv "rtmp://examplebucket.oss-cn-hangzhou.aliyuncs.com/live/test-channel?playlistName=playlist.m3u8&OSSAccessKeyId=LTAI********&Expires=1688543369&Signature=eqK8z0ZTSwznP7fkELy0ckt0Iv***"

    使用OBS進行推流

    1. 安裝OBS Studio

    2. 在頂部導覽列,選擇檔案 > 設定

    3. 在左側導覽列,單擊推流

    4. 在彈出的對話方塊,按以下說明配置各項參數。

      參數

      說明

      服務

      下拉選擇自訂

      伺服器

      填寫步驟1擷取的不包含簽名推流資訊的地址:rtmp://examplebucket.oss-cn-hangzhou.aliyuncs.com/live

      串流密鑰

      填寫步驟1擷取的簽名推流資訊:test-channel?playlistName=playlist.m3u8&OSSAccessKeyId=LTAI**************&Expires=1688543369&Signature=eqK8z0ZTSwznP7fkELy0ck********

    5. 單擊確定

播放推送到OSS的音視頻資料

直播情境

在推流的過程中,可以通過HLS協議播放正在推送的內容。各平台的播放方法如下:

  • 在Android、iOS等移動平台,直接在瀏覽器輸入LiveChannel對應的播放地址即可。

  • Mac OS可以使用safari瀏覽器進行播放。

  • PC端可以安裝VLC多媒體播放器進行播放。安裝完成後,在VLC media player頁面,選擇媒體(M) > 開啟網路串流(N),然後將擷取的播放地址play_url填寫至請輸入網路URL文字框。

為了直播流暢,可以設定較小的FragDuration,例如2s。另外,GOP的大小建議與LiveChannel的FragDuration配置保持一致。OBS的GOP (即keyframe Interval)設定方法如下:

點播情境

推流過程中,OSS總是以直播流的方式推送或更新M3U8。您需要在推流結束後,調用PostVodPlaylist介面組裝一個點播用的m3u8檔案,然後使用該檔案地址來播放。

對於點播的情境,可以設定較大的GOP來減少ts檔案數,從而降低碼率。

相關文檔