Object Storage Service (OSS) supports ingesting H.264-encoded video streams and AAC-encoded audio streams over the Real-Time Messaging Protocol (RTMP). The ingested audio and video data can be used for video-on-demand or live streaming. This topic describes how to ingest audio and video streams into OSS and how to play the ingested data.
Limitations
-
Only RTMP stream ingest is supported. Stream pulling is not supported.
-
The ingested data must contain a video stream in H.264 format.
-
An audio stream is optional. If included, it must be in AAC format; streams in other formats are discarded.
-
Dumping supports only the HTTP Live Streaming (HLS) protocol.
-
Only one client can ingest a stream into a LiveChannel at a time.
Ingest audio and video data into OSS
-
Obtain an ingest URL.
Use an SDK to call the PutLiveChannel API operation to create a LiveChannel and obtain its ingest URL.
-
If the bucket's access control list (ACL) is public-read-write, you can use the obtained ingest URL directly.
-
If the bucket ACL is public-read or private, you must sign the URL. For more information, see Signature V1.
Only the Java and Python SDKs support obtaining ingest URLs.
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.*; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.common.comm.SignVersion; public class Demo { public static void main(String[] args) throws Exception { String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // Obtain access credentials from environment variables. Before you run this sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Specify the bucket name. For example, examplebucket. String bucketName = "examplebucket"; // Specify the LiveChannel name. String liveChannelName = "yourLiveChannelName"; // Specify the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the region to cn-hangzhou. String region = "cn-hangzhou"; // Create an OSSClient instance. // When the OSSClient instance is no longer used, call the shutdown method to release its resources. 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); // Obtain the ingest URLs. List<String> publishUrls = result.getPublishUrls(); for (String item : publishUrls) { // Obtain the ingest URL that does not contain signature information. System.out.println(item); // Obtain the ingest URL that contains signature information. LiveChannelInfo liveChannelInfo = ossClient.getLiveChannelInfo(bucketName, liveChannelName); // The expires parameter specifies the expiration time as a Unix timestamp. This example sets the expiration time to one hour from the current time. long expires = System.currentTimeMillis() / 1000 + 3600; // The playlistName parameter specifies the name that you passed when you called the createLiveChannel operation. If you do not specify this parameter, the default value playlist.m3u8 is used. You can also call the getLiveChannelInfo operation to obtain this name. String signRtmpUrl = ossClient.generateRtmpUri(bucketName, liveChannelName, liveChannelInfo.getTarget().getPlaylistName(), expires); System.out.println(signRtmpUrl); } // Obtain the playback URLs. 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(); } } } }The returned ingest URLs are as follows:
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.m3u8Python
# -*- coding: utf-8 -*- import oss2 from oss2.credentials import EnvironmentVariableCredentialsProvider # Obtain access credentials from environment variables. Before you run this sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set. auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider()) # Specify the endpoint of the region where the bucket is located. For example, if the bucket is in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. # Specify the bucket name. For example, examplebucket. bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket') # Specify the LiveChannel name. For example, 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 # Generate a signed URL for RTMP stream ingest and set the expiration time to 3,600 seconds. signed_publish_url = bucket.sign_rtmp_url(channel_name, "playlist.m3u8", 3600) # Print the unsigned ingest URL. print('publish_url='+publish_url) # Print the signed ingest URL. print('signed_publish_url='+signed_publish_url)The returned ingest URLs are as follows:
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**** -
-
Use the ingest URL to ingest audio and video data into OSS.
The naming convention for files generated by stream ingest is
<channel-name><timestamp>.ts, where<channel-name>is the channel name, and<timestamp>is the timestamp in milliseconds when the file slice is generated.FFmpeg
You can use FFmpeg to ingest a local video file into OSS. For example:
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=eqK8z0ZTSwznP7fkELy0ck***"OBS
-
Install OBS Studio.
-
In the top navigation bar, choose .
-
In the left-side navigation pane, click Stream.
-
Configure the following parameters in the dialog box:
Parameter
Description
Service
From the drop-down list, select Custom.
Server
Enter the URL from Step 1 without the stream ingest signature information:
rtmp://examplebucket.oss-cn-hangzhou.aliyuncs.com/live.Stream Key
Enter the signed stream ingest information that you obtained in Step 1:
test-channel?playlistName=playlist.m3u8&OSSAccessKeyId=LTAI**************&Expires=1688543369&Signature=eqK8z0ZTSwznP7fkELy0ck********. -
Click OK.
-
Play ingested audio and video
Live streaming
During stream ingest, you can play the content by using the HLS protocol. The playback method varies by platform:
-
On mobile platforms such as Android and iOS, open the LiveChannel playback URL in a web browser.
-
On macOS, you can use the Safari browser for playback.
-
On a PC, you can install VLC media player for playback. After installation, open VLC media player, choose , and then enter the playback URL that you obtained into the Please Enter A Network URL text box.
For smooth live streaming, set a short FragDuration (for example, 2 seconds) and a Group of Pictures (GOP) size that matches it. In OBS, this setting is called Keyframe Interval.
In OBS, go to Settings > Output. Set Output Mode to Advanced. On the Streaming tab, set Keyframe Interval (seconds, 0=auto) to 2.
Video-on-demand
During stream ingest, OSS continuously pushes or updates the M3U8 file as a live stream. After the stream ingest ends, you must call the PostVodPlaylist API operation to create a VOD playlist. Use this playlist's URL for playback.
For video-on-demand scenarios, you can set a larger GOP to reduce the number of .ts files, which helps lower the bitrate.