OSS支持使用RTMP协议推送H264编码的视频流和AAC编码的音频流到OSS。推送到OSS的音视频数据可用于点播或直播场景。本文介绍如何推送音视频流到OSS,以及如何播放推送到OSS的音视频数据。
使用限制
只能使用RTMP推流的方式,不支持拉流。
上传的音视频数据中必须包含视频流,且视频流格式为H264。
上传的音视频数据中可选择是否包含音频流。若包含音频流,则只支持AAC格式的音频流,其他格式的音频流会被丢弃。
转储只支持HLS协议。
一个LiveChannel同时只能有一个客户端向其推流。
向OSS推送音视频数据
获取推流地址。
使用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****
使用推流地址向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进行推流
安装OBS Studio。
在顶部导航栏,选择
。在左侧导航栏,单击推流。
在弹出的对话框,按以下说明配置各项参数。
参数
说明
服务
下拉选择自定义。
服务器
填写步骤1获取的不包含签名推流信息的地址:
rtmp://examplebucket.oss-cn-hangzhou.aliyuncs.com/live
。串流密钥
填写步骤1获取的签名推流信息:
test-channel?playlistName=playlist.m3u8&OSSAccessKeyId=LTAI**************&Expires=1688543369&Signature=eqK8z0ZTSwznP7fkELy0ck********
。单击确定。
播放推送到OSS的音视频数据
直播场景
在推流的过程中,可以通过HLS协议播放正在推送的内容。各平台的播放方法如下:
在Android、iOS等移动平台,直接在浏览器输入LiveChannel对应的播放地址即可。
Mac OS可以使用safari浏览器进行播放。
PC端可以安装VLC多媒体播放器进行播放。安装完成后,在VLC media player页面,选择
,然后将获取的播放地址play_url填写至请输入网络URL文本框。
为了直播流畅,可以设置较小的FragDuration,例如2s。另外,GOP的大小建议与LiveChannel的FragDuration配置保持一致。OBS的GOP (即keyframe Interval)设置方法如下:
点播场景
推流过程中,OSS总是以直播流的方式推送或更新M3U8。您需要在推流结束后,调用PostVodPlaylist接口组装一个点播用的m3u8文件,然后使用该文件地址来播放。
对于点播的场景,可以设置较大的GOP来减少ts文件数,从而降低码率。