Media Flow

Oracle Cloud Infrastructure (OCI) Media Flow 服务帮助开发人员将视频和音频媒体处理为不同格式,以便通过 API 和命令行界面 (command-line interface,CLI) 工具按需进行流传输和运行批处理操作。借助 OCI Media Flow,开发人员还可以充实元数据,以在内容管理系统 (CMS) 中轻松容易搜索视频,同时使用 AI 工具显示视频内容并添加功能,例如支持多种语言的隐藏式字幕。

Oracle Cloud Infrastructure Media Flow:概览 (2:02)

OCI Media Flow 的工作原理

OCI Media Flow 的工作原理图
创建视频并将其上传到 Oracle Cloud Infrastructure Object Storage。通过 Oracle Cloud Infrastructure Media Flow,可在可配置的时间间隔内创建视频缩略图,并将其存储在 OCI Object Storage 中。OCI Media Flow 还可创建用于流媒体的多种视频变体,并将用于 HLS 流媒体的视频清单文件添加到客户的文件库中。OCI Media Flow 可创建一个带有 AI 元数据的 JSON 文件,其中包含一个可搜索的内容索引。OCI Media Flow 可创建多个分段的 MP4 和主播放列表,这些是流处理的先决条件。OCI Media Streams 接收有效的 HLS 主播放列表,并为视频流创建视频包。

开发人员如何准备视频文件并进行转码

查看如何创建媒体流和运行 OCI Media Flow 作业。这需要最新的 OCI java SDK,并需要输入输出文件的前缀名称。这仅用于演示,不适用于生产用途。



/***********
This is a demo program to create media flow and run media flow jobs.
This requires the latest java SDK of OCI.
Takes input of the prefix name for the output files.
This is intended for a demonstration only and not for Production usage.
************/

/***********
1. Accept User Input of prefix for the outputs.
2. Create Media Client. 
3. Create Tasks.
4. Create Media Workflow.
5. Create Media Workflow Job.
************/


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.model.MediaWorkflowTask;
import com.oracle.bmc.mediaservices.model.CreateMediaWorkflowDetails;
import com.oracle.bmc.mediaservices.responses.CreateMediaWorkflowResponse;
import com.oracle.bmc.mediaservices.model.MediaWorkflow;
import com.oracle.bmc.mediaservices.requests.*;
import com.oracle.bmc.mediaservices.model.CreateMediaWorkflowJobDetails;
import com.oracle.bmc.mediaservices.model.CreateMediaWorkflowJobByIdDetails;
import com.oracle.bmc.mediaservices.responses.CreateMediaWorkflowJobResponse;
import com.oracle.bmc.mediaservices.model.MediaWorkflowJob;
import org.json.simple.*; 
import org.json.simple.parser.*;
import java.util.Collections;
import java.util.*;
import java.util.Scanner;

public class MediaflowDemoApp {
    // Get User Input
    public static String getUserInput(){
        MediaflowDemoApp.printString("Enter a name for the prefix of files:");
        Scanner input = new Scanner(System.in);
        String prefixInput = input.nextLine();
        input.close();
        return prefixInput;
    }
    // Json String to Json Object
    public static JSONObject createJSONObject(String jsonString){
        JSONObject  jsonObject=new JSONObject();
        JSONParser jsonParser=new  JSONParser();
        if ((jsonString != null) && !(jsonString.isEmpty())) {
            try {
                jsonObject=(JSONObject) jsonParser.parse(jsonString);
            } catch (org.json.simple.parser.ParseException e) {
                e.printStackTrace();
            }
        }
        return jsonObject;
    }
    // Print Function
    public static void printString(Object stringtoPrint){
        System.out.println(stringtoPrint);
    }
    // Create Media Service Client.
    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);
        MediaflowDemoApp.printString("Media Client Instantiated");
        return mediaClient;
    }
    // Close Media Service Client
    public static void closeMediaService(MediaServicesClient mc){
        mc.close();
        MediaflowDemoApp.printString("Media Client Closed");
    }

    // Create Tasks 
    // Tasks are discrete steps in the workflow.
    public static List<MediaWorkflowTask> createTasks(JSONObject arg0,JSONObject arg1,JSONObject arg2,JSONObject arg3,JSONObject arg4){
        long version = 1;
        List<MediaWorkflowTask> task = new ArrayList<MediaWorkflowTask>();
        List<String> typeGetFiles = new ArrayList<String>();
        List<String> typeTranscode = new ArrayList<String>();
        List<String> typeThumbnail = new ArrayList<String>();
        typeGetFiles.add("getFiles");
        typeTranscode.add("transcode1");
        typeThumbnail.add("thumbnail");
        task.add(MediaWorkflowTask.builder().type("getFiles").version(version).key("getFiles").prerequisites(Collections.emptyList()).parameters(arg0).build());
        task.add(MediaWorkflowTask.builder().type("transcribe").version(version).key("transcribe").prerequisites(typeGetFiles).parameters(arg4).build());
        task.add(MediaWorkflowTask.builder().type("transcode").version(version).key("transcode1").prerequisites(typeGetFiles).parameters(arg1).build());
        task.add(MediaWorkflowTask.builder().type("thumbnail").version(version).key("thumbnail").prerequisites(typeTranscode).parameters(arg2).build());
        task.add(MediaWorkflowTask.builder().type("putFiles").version(version).key("PutFiles1").prerequisites(typeThumbnail).parameters(arg3).build());
        return task;
    }
    // Create Media Workflow.
    public static MediaWorkflow createMediaWorkflow(MediaServicesClient mc, List<MediaWorkflowTask> tasks, JSONObject parameters,String compartment_id){
        CreateMediaWorkflowRequest  request = CreateMediaWorkflowRequest.builder().createMediaWorkflowDetails(CreateMediaWorkflowDetails.builder().displayName("test-java-sdk").compartmentId(compartment_id).tasks(tasks).parameters(parameters).build()).build();
        CreateMediaWorkflowResponse response = mc.createMediaWorkflow(request);
        MediaWorkflow mediaflow = response.getMediaWorkflow();
        return mediaflow;
    }
    // Create Media Workflow Job
    public static MediaWorkflowJob createWorkflowJob(MediaServicesClient mc, MediaWorkflow mediaflow, String prefixInput, JSONObject parameters, String compartment_id){
        String mediaWorkflowId = mediaflow.getId();
        CreateMediaWorkflowJobRequest request = CreateMediaWorkflowJobRequest.builder().createMediaWorkflowJobDetails(CreateMediaWorkflowJobByIdDetails.builder().displayName("test-java-sdk-job").compartmentId(compartment_id).mediaWorkflowId(mediaWorkflowId).parameters(parameters).build()).build();
        CreateMediaWorkflowJobResponse response = mc.createMediaWorkflowJob(request);
        MediaWorkflowJob mediaflowJob = response.getMediaWorkflowJob();
        return mediaflowJob;
    }

    public static void main(String[] args) {

        // **Variable Declarations** //
        String compartment_id = "ocid1.compartment.oc1..aaaaaaaabhuut4zoztxlfneotrwuauqt5wjhmj4kxaka6ajme4ipxqlcwv6a";
        String src_bucket = "test";
        String dst_bucket = "test";
        String namespace = "test";
        String src_video = "test";
        String prefix_input = "test";
        
        //* Task Parameters *//
        String getobjectParameters = "{\"taskParameters\": [{\"storageType\": \"objectStorage\",\"target\": \"getFiles/${/input/objectName}\",\"namespaceName\": \"${/input/namespaceName}\",\"bucketName\": \"${/input/bucketName}\",\"objectName\": \"${/input/objectName}\"}]}";
        String transcodeParameters = "{ \"transcodeType\": \"standardTranscode\", \"standardTranscode\": { \"input\": \"${/getFiles/taskParameters/0/target}\", \"outputPrefix\": \"${/transcode/outputPrefix}\", \"videoCodec\": \"h264\", \"audioCodec\": \"aac\", \"packaging\": { \"packageType\": \"hls\", \"segmentLength\": 6 }, \"ladder\": [ { \"size\": { \"height\": 1080, \"resizeMethod\": \"scale\" } }, { \"size\": { \"height\": 720, \"resizeMethod\": \"scale\" } }, { \"size\": { \"height\": 480, \"resizeMethod\": \"scale\" } }, { \"size\": { \"height\": 360, \"resizeMethod\": \"scale\" } } ] } }";
        String thumbnailParameters = "{ \"thumbnails\": { \"input\": \"${/getFiles/taskParameters/0/target}\", \"frameSelectors\": [ { \"namePrefix\": \"thumb\", \"format\": \"jpg\", \"sizes\": [ { \"width\": 390 }, { \"width\": 196 } ], \"clipImagePicker\": { \"percentList\": { \"pickList\": [ 10, 20, 30 ] } } } ] } }";
        String finaltaskParameters = "{ \"taskParameters\": [ { \"namespaceName\": \"${/output/namespaceName}\", \"bucketName\": \"${/output/bucketName}\", \"source\": \"${/transcode/outputPrefix}*.m3u8\", \"objectName\": \"${/output/objectNamePath}${/transcode/outputPrefix}\", \"assetCompartmentId\": \"${/output/assetCompartmentId}\", \"registerMetadata\": true }, { \"namespaceName\": \"${/output/namespaceName}\", \"bucketName\": \"${/output/bucketName}\", \"source\": \"master.m3u8\", \"objectName\": \"${/output/objectNamePath}${/transcode/outputPrefix}-master.m3u8\", \"assetCompartmentId\": \"${/output/assetCompartmentId}\", \"registerMetadata\": true }, { \"namespaceName\": \"${/output/namespaceName}\", \"bucketName\": \"${/output/bucketName}\", \"source\": \"*.fmp4\", \"objectName\": \"${/output/objectNamePath}\", \"assetCompartmentId\": \"${/output/assetCompartmentId}\", \"registerMetadata\": true }, { \"namespaceName\": \"${/output/namespaceName}\", \"bucketName\": \"${/output/bucketName}\", \"source\": \"*.${/thumbnail/thumbnails/frameSelectors/0/format}\", \"objectName\": \"${/output/objectNamePath}${/transcode/outputPrefix}-\", \"assetCompartmentId\": \"${/output/assetCompartmentId}\", \"registerMetadata\": true } ] }";
        String transcibeParmeters = "{ \"inputVideo\": \"${/getFiles/taskParameters/0/target}\", \"outputAudio\": \"${/output/objectNamePath}${/transcode/outputPrefix}.wav\", \"outputBucketName\": \"${/output/bucketName}\", \"outputNamespaceName\": \"${/output/namespaceName}\", \"outputTranscriptionPrefix\": \"${/output/objectNamePath}${/transcode/outputPrefix}\", \"transcriptionJobCompartment\": \"${/output/assetCompartmentId}\", \"waitForCompletion\" : true }";
        String mediaworkflowParameters = "{ \"input\": { \"objectName\": \"${/video/srcVideo}\", \"bucketName\": \"${/video/srcBucket}\", \"namespaceName\": \"${/video/namespace}\" }, \"output\": { \"bucketName\": \"${/video/dstBucket}\", \"namespaceName\": \"${/video/namespace}\", \"assetCompartmentId\": \"${/video/compartmentID}\", \"objectNamePath\": \"sdk_test/${/input/objectName}/\" }, \"transcode\": { \"outputPrefix\": \"${/video/outputPrefixName}\" } }";
        String mediaflowjobParameters = "{ \"video\": { \"srcBucket\": \"" + src_bucket+ "\", \"dstBucket\": \"" +dst_bucket+ "\", \"namespace\": \"" +namespace+ "\", \"compartmentID\": \""+compartment_id+"\", \"srcVideo\": \""+src_video+"\", \"outputPrefixName\" : \""+prefix_input+"\" } }";
        //* Json Objects of the task parameters *//
        JSONObject getobjectParametersJson = MediaflowDemoApp.createJSONObject(getobjectParameters);
        JSONObject transcodeParametersJson = MediaflowDemoApp.createJSONObject(transcodeParameters);
        JSONObject thumbnailParametersJson = MediaflowDemoApp.createJSONObject(thumbnailParameters);
        JSONObject finaltaskParametersJson = MediaflowDemoApp.createJSONObject(finaltaskParameters);
        JSONObject transcibeParmetersJson = MediaflowDemoApp.createJSONObject(transcibeParmeters);
        JSONObject mediaworkflowParametersJson = MediaflowDemoApp.createJSONObject(mediaworkflowParameters);
        JSONObject mediaflowjobParametersJson = MediaflowDemoApp.createJSONObject(mediaflowjobParameters);
        
        /* Debug JSON Prints
        MediaflowDemoApp.printString(getobjectParametersJson);
        MediaflowDemoApp.printString(transcodeParametersJson);
        MediaflowDemoApp.printString(thumbnailParametersJson);
        MediaflowDemoApp.printString(finaltaskParametersJson);
        MediaflowDemoApp.printString(transcibeParmetersJson);
        MediaflowDemoApp.printString(mediaworkflowParametersJson);
        MediaflowDemoApp.printString(mediaflowjobParametersJson);*/
        
        // Get User Input
        String prefixInput = MediaflowDemoApp.getUserInput();
        // Create the tasks for mediaflow
        List<MediaWorkflowTask> tasks = MediaflowDemoApp.createTasks(getobjectParametersJson,transcodeParametersJson,thumbnailParametersJson,finaltaskParametersJson,transcibeParmetersJson);
        // Connect to media services 
        MediaServicesClient mediaClient = MediaflowDemoApp.connectMediaService();
        // Create MediaWorkFlow 
        MediaWorkflow mediaflow = MediaflowDemoApp.createMediaWorkflow(mediaClient, tasks, mediaworkflowParametersJson, compartment_id);
        // Prints MediaWorkflow OCID
        MediaflowDemoApp.printString(mediaflow.getId());
        // Create the Workflow Job
        MediaWorkflowJob mediaflowJob = MediaflowDemoApp.createWorkflowJob(mediaClient, mediaflow, prefixInput, mediaflowjobParametersJson, compartment_id);
        // Print Workflow Job ID
        MediaflowDemoApp.printString(mediaflowJob.getId());
        // Finally Close the Media Client
        MediaflowDemoApp.closeMediaService(mediaClient);
    }
}
	

OCI Media Flow 的使用场景

存储和管理视频

OCI Media Flow 提供元数据来处理视频并将其存储在 CMS 中,对视频进行转码以供传送,创建多个版本的视频以播放不同的视频分辨率,并创建主播放列表以准备流式传输。

剪辑视频

您可以更轻松地剪辑视频。在选择所需的分辨率和配置后,OCI Media Flow 可以自动为热门社交媒体站点提供合适的视频格式,方便与不同受众分享。

创建学习平台

通过 OCI Media Flow 为学习平台体验轻松创建、处理和存储视频,并保证提供高质量的客户体验。

归档视频

OCI Media Flow 简化了归档视频的处理、管理和内容搜索,从而提高可搜索性。OCI Object Storage 可大规模、低成本地存储视频。

2022 年 7 月 20 日

Oracle 推出 OCI Digital Media Services,加速 OCI 中的视频运营

甲骨文公司首席产品经理 Remi Fourreau

我们很高兴宣布 Oracle Cloud Infrastructure (OCI) 中的 Digital Media Services (DMS) 已全面上市。拥有视频内容的 OCI 客户可以利用低成本的媒体处理功能以及 DMS Media Flow 和 DMS Media Streams 服务的媒体分发功能。这些服务可以使用新的媒体功能来增强应用和业务流程,从而创造更好的客户体验并改善业务运营。

阅读全文

精选博客

查看全部

赶快行动

享用 Always Free 云技术服务,并试用 30 天的收费服务

Oracle 提供的 Free Tier 无时间限制,包含了 Media Flow、Media Streams、AI Services 等服务,另外还有 300 美元的免费储值,让您可以试用其他云技术服务。立即获取详细信息并注册您的免费账户。

  • Oracle Cloud Free Tier 包含哪些内容?

    • 永久免费
    • 2 个 Autonomous Database,各 20 GB
    • 计算虚拟机
    • 100 GB 块存储卷
    • 10 GB 对象存储空间

联系销售

想了解更多有关 Media Flow 的信息?让我们的专家为您提供帮助。

  • 专家能为您解答以下问题:

    • 哪些服务与 OCI Media Flow 无缝集成?
    • 我的方案定价是怎样的?
    • Media Flow 支持哪些不同的视频格式?

注:为免疑义,本网页所用以下术语专指以下含义:

  1. 除Oracle隐私政策外,本网站中提及的“Oracle”专指Oracle境外公司而非甲骨文中国 。
  2. 相关Cloud或云术语均指代Oracle境外公司提供的云技术或其解决方案。