Media Streams

Oracle Cloud Infrastructure (OCI) Media Streams is a service that helps developers package video content to stream it from OCI or through a content delivery network (CDN). It encrypts media content for secure delivery to devices, including smart televisions, mobile devices, computers, and gaming consoles. Developers can now take advantage of the scalability of OCI to deliver a complete video experience without having to manage infrastructure.

Oracle Cloud Infrastructure Media Streams: Overview (1:31)

How OCI Media Streams works

How OCI Media Streams works diagram
A video is created and uploaded to Oracle Cloud Infrastructure Object Storage. Through Oracle Cloud Infrastructure Media Flow, thumbnail stills from the video are created from configurable intervals of time and can be stored in OCI Object Storage. OCI Media Flow also creates multiple variants of the video for streaming, and video manifest files for HLS streaming are added to the customer’s file repository. OCI Media Flow creates a JSON file with AI metadata that contains a searchable content index. OCI Media Flow creates the multiple fragmented MP4 and master playlist that are prerequisites for streaming. OCI Media Streams ingests a valid HLS master playlist and creates video packages for video streaming.

How developers can prepare and transcode video files

See how to stream media and run OCI Media Streams jobs. This requires the latest Java SDK of OCI, and the master playlist name and the residing bucket name must be input. This is intended for demonstration only and is not for production usage.



/***********
This is a demo program to create media streams.
This requires the latest java SDK of OCI.
Takes input of the master playlist name and residing bucket name.
This is intended for a demonstration only and not for Production usage.
************/

/***********
1. Accept User Input of Object Storage Bucket name & HLS Master playlist (m3u8).
(Note: This takes only master.m3u8 and not sub-playlists as input)
2. Create Media Client. 
3. Create Distribution Channel.
4. Configure CDN for Distribution Channel.
5. Create Stream Packaging Configuration.
6. Create Asset ID  for the provided input master playlist.
7. Ingest the Asset ID into the Distribution Channel.
8. Create MediaStreams Client with distribution channel as endpoint. 
9. After Ingest complete, generate Session Token. 
10. Display's URL that is HLS streamable. 
************/

import com.oracle.bmc.auth.InstancePrincipalsAuthenticationDetailsProvider;
import com.oracle.bmc.auth.AuthenticationDetailsProvider;
import com.oracle.bmc.auth.ConfigFileAuthenticationDetailsProvider;
import com.oracle.bmc.mediaservices.MediaServicesClient;
import com.oracle.bmc.mediaservices.*;
import com.oracle.bmc.mediaservices.requests.*;
import com.oracle.bmc.mediaservices.responses.*;
import com.oracle.bmc.mediaservices.model.*;
import com.oracle.bmc.mediaservices.requests.CreateStreamCdnConfigRequest;
import com.oracle.bmc.mediaservices.requests.CreateStreamDistributionChannelRequest;
import com.oracle.bmc.mediaservices.requests.CreateMediaAssetRequest;
import com.oracle.bmc.mediaservices.requests.CreateStreamPackagingConfigRequest;
import com.oracle.bmc.mediaservices.requests.IngestStreamDistributionChannelRequest;
import com.oracle.bmc.mediaservices.responses.CreateMediaAssetResponse;
import com.oracle.bmc.mediaservices.responses.CreateStreamCdnConfigResponse;
import com.oracle.bmc.mediaservices.responses.CreateStreamDistributionChannelResponse;
import com.oracle.bmc.mediaservices.responses.CreateStreamPackagingConfigResponse;
import com.oracle.bmc.mediaservices.responses.IngestStreamDistributionChannelResponse;
import com.oracle.bmc.mediaservices.model.IngestStreamDistributionChannelResult;
import com.oracle.bmc.mediaservices.model.MediaAsset;
import com.oracle.bmc.mediaservices.model.StreamCdnConfig;
import com.oracle.bmc.mediaservices.model.StreamDistributionChannel;
import com.oracle.bmc.mediaservices.model.StreamPackagingConfig;
import com.oracle.bmc.mediaservices.MediaStreamClient;
import com.oracle.bmc.mediaservices.model.CreateStreamDistributionChannelDetails;
import com.oracle.bmc.mediaservices.model.CreateStreamCdnConfigDetails;
import com.oracle.bmc.mediaservices.model.IngestStreamDistributionChannelDetails;
import com.oracle.bmc.mediaservices.requests.CreateStreamDistributionChannelRequest;
import com.oracle.bmc.mediaservices.model.EdgeStreamCdnConfig;
import com.oracle.bmc.mediaservices.model.StreamCdnConfigSection;
import com.oracle.bmc.mediaservices.model.CreateStreamPackagingConfigDetails.StreamPackagingFormat;
import com.oracle.bmc.mediaservices.model.StreamPackagingConfigEncryptionNone;
import com.oracle.bmc.mediaservices.model.AssetType;
import com.oracle.bmc.mediaservices.requests.GenerateSessionTokenRequest;
import com.oracle.bmc.mediaservices.model.GenerateSessionTokenDetails;
import com.oracle.bmc.mediaservices.requests.GetMediaWorkflowJobRequest;
import com.oracle.bmc.mediaservices.responses.GetMediaWorkflowJobResponse;
import com.oracle.bmc.mediaservices.model.MediaWorkflowJob.LifecycleState;

import org.json.simple.*; 
import org.json.simple.parser.*;
import java.util.Collections;
import java.util.*;
import java.util.Scanner;

public class MediastreamsDemoApp {

    // User Input 
    public static String[] getUserInput(){
        String[] inputs = new String[2];
        MediastreamsDemoApp.printString("\n", "Enter name of bucket where master playlist is located:");
        Scanner input = new Scanner(System.in);
        String inputBucketName = input.nextLine();
        MediastreamsDemoApp.printString("\n","Enter name of master playlist to be ingested:");
        String inputPlaylistName = input.nextLine();
        input.close();
        inputs[0] = inputBucketName;
        inputs[1] = inputPlaylistName;
        return inputs;
    }
    // Print Function
    public static void printString(Object stringtoPrint , Object stringtoPrint2){
        System.out.println(stringtoPrint);
        System.out.println(stringtoPrint2);
    }

    // Media Client Creation by default with Instance Principal.
    // Toggle the other java lines in this code for User Principal.
    public static MediaServicesClient connectMediaService(){
        InstancePrincipalsAuthenticationDetailsProvider provider = InstancePrincipalsAuthenticationDetailsProvider.builder().build();
        MediaServicesClient mediaClient =  new MediaServicesClient(provider);
        // User Principal
        // Read config from the profile DEFAULT in the file "~/.oci/config". You can switch to different profile.
        // AuthenticationDetailsProvider authenticationDetailsProvider = new ConfigFileAuthenticationDetailsProvider(PROFILE_DEFAULT);
        // MediaServicesClient mediaClient = MediaServicesClient.builder().build(authenticationDetailsProvider);
        return mediaClient;
    }
    // Closing Media Client
    public static void closeMediaService(MediaServicesClient mc,MediaStreamClient ms){
        mc.close();
        ms.close();
        MediastreamsDemoApp.printString("\n", "Media Clients are Closed");
    }
    // Create Media Streams Client 
    // Default this program creates using Instance Principal
    public static MediaStreamClient connectMediaStreams(StreamDistributionChannel dc){
        String endpoint = dc.getDomainName();
        InstancePrincipalsAuthenticationDetailsProvider provider = InstancePrincipalsAuthenticationDetailsProvider.builder().build();
        MediaStreamClient mediaStreamsClient =  new MediaStreamClient(provider);
        // User Principal
        // Read config from the profile DEFAULT in the file "~/.oci/config". You can switch to different profile.
        // AuthenticationDetailsProvider authenticationDetailsProvider = new ConfigFileAuthenticationDetailsProvider(PROFILE_DEFAULT);
        // MediaStreamClient mediaStreamsClient = MediaStreamClient.builder().build(authenticationDetailsProvider);
        mediaStreamsClient.setEndpoint("https://"+endpoint);
        MediastreamsDemoApp.printString("\n" ,"Media Streams Client Instatiated Successfully");
        return mediaStreamsClient;
    }
    // Create Distribution Channel 
    public static StreamDistributionChannel createDistributionChannel(MediaServicesClient mc, String compartment_id){
        CreateStreamDistributionChannelRequest  request = CreateStreamDistributionChannelRequest.builder().createStreamDistributionChannelDetails(CreateStreamDistributionChannelDetails.builder().displayName("test-java-sdk").compartmentId(compartment_id).build()).build();
        CreateStreamDistributionChannelResponse response = mc.createStreamDistributionChannel(request);
        StreamDistributionChannel dc = response.getStreamDistributionChannel();
        return dc;
    }
    //Create CDN - In this case, its OCI Edge.
    public static void createCDN(MediaServicesClient mc, String compartment_id, StreamDistributionChannel dc){
        String channelId = dc.getId();
        CreateStreamCdnConfigRequest  request = CreateStreamCdnConfigRequest.builder().createStreamCdnConfigDetails(
                                                                        CreateStreamCdnConfigDetails.builder().displayName("test-java-sdk").isEnabled(true).distributionChannelId(channelId).config(EdgeStreamCdnConfig.builder().build()).build()).build();
        CreateStreamCdnConfigResponse response = mc.createStreamCdnConfig(request);
        StreamCdnConfig cdnConfig = response.getStreamCdnConfig();
    }
    // Create Streaming Package Configuration 
    // By default Unencrypted in this code. 
    public static StreamPackagingConfig createStreamPackage(MediaServicesClient mc, StreamDistributionChannel dc){
        String channelId = dc.getId();
        // Unencrypted Stream
        CreateStreamPackagingConfigRequest  request = CreateStreamPackagingConfigRequest.builder().createStreamPackagingConfigDetails(CreateStreamPackagingConfigDetails.builder().displayName("test-java-sdk").distributionChannelId(channelId).streamPackagingFormat(CreateStreamPackagingConfigDetails.StreamPackagingFormat.valueOf("Hls")).segmentTimeInSeconds(6).encryption(StreamPackagingConfigEncryptionNone.builder().build()).build()).build();
        // AES 128 encrypted stream
        //CreateStreamPackagingConfigRequest  request = CreateStreamPackagingConfigRequest.builder().createStreamPackagingConfigDetails(CreateStreamPackagingConfigDetails.builder().displayName("test-java-sdk").distributionChannelId(channelId).streamPackagingFormat(CreateStreamPackagingConfigDetails.StreamPackagingFormat.valueOf("Hls")).segmentTimeInSeconds(6).encryption(StreamPackagingConfigEncryptionAes128.builder().build()).build()).build();
        CreateStreamPackagingConfigResponse response = mc.createStreamPackagingConfig(request);
        StreamPackagingConfig packageConfig = response.getStreamPackagingConfig();
        return packageConfig;
    }
    // Create Media Asset ID for given master playlist 
    public static MediaAsset createAsset(MediaServicesClient mc, String inputBucket,String masterPlayList, String namespace, String compartmentId){
        CreateMediaAssetRequest  request = CreateMediaAssetRequest.builder().createMediaAssetDetails(CreateMediaAssetDetails.builder().bucketName(inputBucket).displayName("test-java-sdk").objectName(masterPlayList).namespaceName(namespace).type(AssetType.valueOf("Playlist")).compartmentId(compartmentId).build()).build();
        CreateMediaAssetResponse response = mc.createMediaAsset(request);
        MediaAsset mediaAsset = response.getMediaAsset();
        return mediaAsset;
    }
    // Ingest the Master Playlist to Distribution Channel 
    public static IngestStreamDistributionChannelResult ingestAsset(MediaServicesClient mc, MediaAsset ma, StreamDistributionChannel dc, String compartmentId){
        String assetId = ma.getId();
        String channelId = dc.getId();
        IngestStreamDistributionChannelRequest request = IngestStreamDistributionChannelRequest.builder().ingestStreamDistributionChannelDetails(AssetMetadataEntryDetails.builder().mediaAssetId(assetId).compartmentId(compartmentId).build()).streamDistributionChannelId(channelId).build();
        IngestStreamDistributionChannelResponse response = mc.ingestStreamDistributionChannel(request);
        IngestStreamDistributionChannelResult ingestResult = response.getIngestStreamDistributionChannelResult();
        return ingestResult;
    }
    // Get the Media WorkflowJob ID for the Ingest Job
    public static MediaWorkflowJob checkIngestJobStatus(MediaServicesClient mc, IngestStreamDistributionChannelResult ingestStatus) {
        String mediaWorkflowId = ingestStatus.getMediaWorkflowJobId(); 
        GetMediaWorkflowJobRequest request = GetMediaWorkflowJobRequest.builder().mediaWorkflowJobId(mediaWorkflowId).build();
        GetMediaWorkflowJobResponse response = mc.getMediaWorkflowJob(request);
        MediaWorkflowJob mediaWorkflowJob = response.getMediaWorkflowJob();
        return mediaWorkflowJob;
    }
    // Check the status of the Ingest Job using above Media Workflow Job ID
    public static String jobLifecycleState(MediaServicesClient mediaClient,IngestStreamDistributionChannelResult ingestStatus){
        MediaWorkflowJob mediaWorkflowJob = MediastreamsDemoApp.checkIngestJobStatus(mediaClient,ingestStatus);
        MediaWorkflowJob.LifecycleState lifestate = mediaWorkflowJob.getLifecycleState();
        String ingestCurrentStatus = lifestate.getValue();
        return ingestCurrentStatus;
    }
    // Create Session Token 
    // Defaults to 24 hour validity 
    public static SessionToken generateSessionToken(MediaStreamClient ms, StreamPackagingConfig sp, MediaAsset ma){
        String streamPackagingId = sp.getId();
        String mediaAssetId = ma.getId();
        List<GenerateSessionTokenDetails.Scopes> scopes = new ArrayList<GenerateSessionTokenDetails.Scopes>();
        scopes.add(GenerateSessionTokenDetails.Scopes.valueOf("Edge")); 
        scopes.add(GenerateSessionTokenDetails.Scopes.valueOf("Playlist"));
        List<String> assetIds = new ArrayList<String>();
        assetIds.add(mediaAssetId);
        GenerateSessionTokenRequest request = GenerateSessionTokenRequest.builder().generateSessionTokenDetails(GenerateSessionTokenDetails.builder().packagingConfigId(streamPackagingId).scopes(scopes).assetIds(assetIds).build()).build();
        GenerateSessionTokenResponse response = ms.generateSessionToken(request);
        SessionToken sessionToken = response.getSessionToken();
        return sessionToken;

    }

    public static void spinningWheel() throws InterruptedException{
        String a = "|/-\\";
        while (true) {
            for (int i = 0; i < 4; i++) {
                System.out.print("\033[0;0H");   // place cursor at top left corner
                for (int j = 0; j < 80; j++) {   // 80 character terminal width, say
                    System.out.print(a.charAt(i));
                }
                Thread.sleep(250);
            }
        }
    }

    public static void main(String[] args) throws InterruptedException{

        // **Variable Declarations** //
        String compartment_id = "ocid1.compartment.oc1..aaaaaaaabhuut4zoztxlfneotrwuauqt5wjhmj4kxaka6ajme4ipxqlcwv6a";
        String namespace = "axjagzvlc4vi";
        
        String [] inputs = MediastreamsDemoApp.getUserInput();
        String inputBucket = inputs[0];
        String masterPlayList = inputs[1];
        // Connect to media services 
        MediaServicesClient mediaClient = MediastreamsDemoApp.connectMediaService();
        MediastreamsDemoApp.printString("\n", "Media Client Instatiated Successfully");
        // Create Distribution Channel
        StreamDistributionChannel distributionChannel = MediastreamsDemoApp.createDistributionChannel(mediaClient, compartment_id);
        MediastreamsDemoApp.printString("\n Distribution Channel Created Successfully",distributionChannel.getId());
        // Configure CDN for the distribution channel
        MediastreamsDemoApp.createCDN(mediaClient, compartment_id, distributionChannel);
        // Create stream packaging Configuration
        StreamPackagingConfig streamPackageConfig = MediastreamsDemoApp.createStreamPackage(mediaClient, distributionChannel);
        MediastreamsDemoApp.printString("\n Streaming Packaging Configuration Created Successfully", streamPackageConfig.getId());
        // Create Media Asset for provided master playlist
        MediaAsset mediaAsset = MediastreamsDemoApp.createAsset(mediaClient, inputBucket, masterPlayList, namespace, compartment_id);
        MediastreamsDemoApp.printString("\n Media Asset Registered Successfully" , mediaAsset.getId());
        // Initiate Ingest of the master playlist into the Distribution channel
        IngestStreamDistributionChannelResult ingestStatus = MediastreamsDemoApp.ingestAsset(mediaClient, mediaAsset, distributionChannel, compartment_id);
        MediastreamsDemoApp.printString("\n Ingest of Asset Initiated with Job", ingestStatus.getMediaWorkflowJobId());
        // Run Loop for ingest job to complete.      
        boolean status = false;
        System.out.print("Ingesting");
        while (!status){
            String ingestValue = MediastreamsDemoApp.jobLifecycleState(mediaClient,ingestStatus);
            System.out.print(".");
            Thread.sleep(3000);
            //System.out.println(ingestCurrentStatus);
            if ((ingestValue == "SUCCEEDED") || (ingestValue == "FAILED")){
                break;
            }
        }
        String ingestOutcome = MediastreamsDemoApp.jobLifecycleState(mediaClient,ingestStatus);
        MediastreamsDemoApp.printString("\nIngest Completed with status", ingestOutcome);

        if (ingestOutcome == "SUCCEEDED") {
            // Create media Streams Client with distribution cahnnel 
            MediaStreamClient mediaStreamsClient = MediastreamsDemoApp.connectMediaStreams(distributionChannel);
            // Generate session token for the master playlist.
            SessionToken sessionToken = MediastreamsDemoApp.generateSessionToken(mediaStreamsClient, streamPackageConfig, mediaAsset);
            //MediastreamsDemoApp.printString(sessionToken.getToken());
            MediastreamsDemoApp.printString("\n\nStream Media with your player:\n\n","https://"+distributionChannel.getDomainName()+"/20211101/actions/generatePlaylist?mediaAssetId="+mediaAsset.getId()+"&streamPackagingConfigId="+streamPackageConfig.getId()+"&token="+sessionToken.getToken());
            // Close the Media Clients
            MediastreamsDemoApp.closeMediaService(mediaClient,mediaStreamsClient);
        }
        else {
            mediaClient.close();
        }

    }
}
	

OCI Media Streams use cases

  • Access and package video content

    Make it easier to access stored videos through asset IDs with OCI Media Streams, which packages content so you only need to transcode content once to stream it across various device types and formats. Content encryption and streaming formats are applied dynamically to maximize developer time and effort.

  • Clip videos

    After OCI Media Flow delivers the right video format for popular social media sites, OCI Media Streams packages video content and encrypts it to stream from a variety of devices, including mobile phones and gaming consoles.

  • Create a learning platform

    Create, process, and store videos for a learning platform experience with OCI Media Flow. Then use OCI Media Streams to package and encrypt content for secure delivery and streaming. Strong content encryption methods ensure that your videos only stream where you want them to.

Oracle launches OCI Digital Media Services to accelerate video operations in OCI

Remi Fourreau, Principal Product Manager, Oracle

We’re excited to announce the general availability of Digital Media Services (DMS) in Oracle Cloud Infrastructure (OCI). OCI customers with video content can leverage the low-cost media processing capabilities with DMS Media Flow and media distribution with DMS Media Streams services. These services can enhance applications and business processes with new media capabilities that create better customer experiences and improve business operations.

Read the complete post

Featured OCI Media Flow blogs

View all

Get started with OCI Media Streams

Try Always Free cloud services and get a 30-day trial

Oracle offers a Free Tier with no time limits on selection of services like Media Streams, Media Flow, and AI Services as well as US$300 in free credits to try additional cloud services. Get the details and sign up for your free account today.

  • What's included with Oracle Cloud Free Tier?

    • Always Free
    • 2 Autonomous Databases, 20 GB each
    • Compute VMs
    • 100 GB block volume
    • 10 GB object storage

Contact sales

Interested in learning more about Media Streams? Let one of our experts help.

  • They can answer questions like:

    • Which services integrate seamlessly with OCI Media Streams?
    • What does pricing look like for my scenarios?
    • How can I protect my video content delivery?