利用Meida Service的Java SDK来调用Azure Media Services的Index V2实现视频字幕自动识别

Azure Media Services新的Index V2 支持自动将视频文件中的语音自动识别成字幕文件WebVtt,非常方便的就可以跟Azure Media Player集成,将一个原来没字幕的视频文件自动配上一个对应语言的字幕。而且强大的语音识别功能支持识别多国语言包括:

  • English [EnUs]
  • Spanish [EsEs]
  • Chinese [ZhCn]
  • French [FrFr]
  • German [DeDe]
  • Italian [ItIt]
  • Portuguese [PtBr]
  • Arabic (Egyptian) [ArEg]

 

从上面列表我们可以看到这个Index  V2是支持中文的识别,如果公司里已经存在了大量演讲或者课程视频但是又没有配上字幕的话,Media Services的Index V2功能,能够很好的帮上忙。

下面我们试试用Java的代码来调用Media Services的这个功能:

引用Media Service的相关SDK,我们需要在pom.xml增加几个dependency

<dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure</artifactId>
        <version>1.0.0-beta2</version>
   </dependency>
  <dependency>
      <groupId>com.microsoft.azure</groupId>
      <artifactId>azure-media</artifactId>
      <version>0.9.4</version>
</dependency>

首先我们准备好访问Media Service的基本资料,譬如账号和登录的Key

// Media Services account credentials configuration
    private static String mediaServiceUri = "https://media.windows.net/API/";
    private static String oAuthUri = "https://wamsprodglobal001acs.accesscontrol.windows.net/v2/OAuth2-13";
    private static String clientId = "wingsample";
    private static String clientSecret = "p8BDkk+kLYZzpnvP0B5KFy98uLTv7ALGuSX7F9LmHtk=";
    private static String scope = "urn:WindowsAzureMediaServices";

然后就是创建一个访问Media Service的Context

public static MediaContract getMediaService(){
            
         Configuration configuration = MediaConfiguration.configureWithOAuthAuthentication(
                 mediaServiceUri, oAuthUri, clientId, clientSecret, scope);
         MediaContract  mediaService = MediaService.create(configuration);
    
         return mediaService;
    }

为了能够调用一个processor来执行index,我们需要一个获取处理起的方法:

public static MediaProcessorInfo getLatestProcessorByName(MediaContract mediaService,String processname){
        ListResult<MediaProcessorInfo> mediaProcessors;
        try {
            mediaProcessors = mediaService
                    .list(MediaProcessor.list().set("$filter", String.format("Name eq '%s'", processname)));
        
         // Use the latest version of the Media Processor
        MediaProcessorInfo mediaProcessor = null;
        for (MediaProcessorInfo info : mediaProcessors) {
            if (null == mediaProcessor || info.getVersion().compareTo(mediaProcessor.getVersion()) > 0) {
                mediaProcessor = info;
                return mediaProcessor;
            }
        }
        } catch (ServiceException e) {
            // TODO Auto-generated catch block
            ;e.printStackTrace();
        }
        return null;
    }

当然我们好需要根据Asset的Id来获取到某个具体的Asset来进行处理

public static AssetInfo getAssetById(MediaContract mediaService,String assetName) throws ServiceException
    {
        AssetInfo    resultAsset = mediaService.get(Asset.get(assetName));
     return resultAsset;
    }

有了AssetInfo,processor,和mediaserivce的Context,我们就可以执行Index V2

public static String index2(MediaContract mediaService,AssetInfo assetInfo)
    {
        try
        {
            logger.info("start index2: " + assetInfo.getName());
           
            String config = "{"+
                  "\"version\":\"1.0\","+
                  "\"Features\":"+
                    "["+
                       "{"+
                       "\"Options\": {"+
                        "    \"Formats\":[\"WebVtt\",\"ttml\"],"+
                            "\"Language\":\"enUs\","+
                            "\"Type\":\"RecoOptions\""+
                       "},"+
                       "\"Type\":\"SpReco\""+
                    "}]"+
                "}";
          
            String taskXml = "<taskBody><inputAsset>JobInputAsset(0)</inputAsset>"
                    + "<outputAsset assetCreationOptions=\"0\"" // AssetCreationOptions.None
                    + " assetName=\"" + assetInfo.getName()+"index 2" + "\">JobOutputAsset(0)</outputAsset></taskBody>";
            
            System.out.println("config: " + config);
            MediaProcessorInfo indexerMP =
                getLatestProcessorByName(mediaService,"Azure Media Indexer 2 Preview");
                
                // Create a task with the Indexer Media Processor
                Task.CreateBatchOperation task =
                    Task.create(indexerMP.getId(), taskXml)
                        .setConfiguration(config)
                        .setName(assetInfo.getName() + "_Indexing");
                
                Job.Creator jobCreator = Job.create()
                    .setName(assetInfo.getName() + "_Indexing")
                    .addInputMediaAsset(assetInfo.getId())
                    .setPriority(2)
                    .addTaskCreator(task);
                
                final JobInfo jobInfo;
                final String jobId;
                synchronized (mediaService)
                {
                    jobInfo = mediaService.create(jobCreator);
                    jobId = jobInfo.getId();
                }
           //     checkJobStatus(jobId, assetInfo.getName());
                
                return jobId;//downloadAssetFilesFromJob(jobInfo);
            }
            catch (Exception e)
            {
                logger.error("Exception occured while running indexing job: "
                    + e.getMessage());
            }
            return "";
        }

这些方法都写好了,我们就可以直接在Main函数里面执行它了

public static void main( String[] args )
    {
        try {
        MediaContract mediaService=getMediaService();
        AssetInfo asset;
        
    asset = getAssetById(mediaService,"nb:cid:UUID:13144339-d09b-4e6f-a86b-3113a64dbabe");
        
        String result=index2(mediaService,asset);
           System.out.println( "Job:"+result );
    } catch (ServiceException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    }

从Index2这个函数里面我们有两个东西是很重要的。一个是json格式preset结构,我们如果需要更改识别语言,生成的格式的话,只需要对这个Json文件进行更改就好了。

{
  "version":"1.0",
  "Features":
    [
       {
       "Options": {
            "Formats":["WebVtt","ttml"],
            "Language":"enUs",
            "Type":"RecoOptions"
       },
       "Type":"SpReco"
    }]
}

一个是Task的描述XML,这个XML是用来描述这个任务是处理那个Asset,处理完放到那个Asset里面。基本上跟Media Service相关的各种编码,识别都需要这个task的xml配合对应的preset文件来处理的。

<?xml version="1.0" encoding="utf-16"?>
<taskBody>
  <inputAsset>JobInputAsset(0)</inputAsset>
  <outputAsset assetCreationOptions="0" assetName="ep48_mid.mp4index 2">JobOutputAsset(0)</outputAsset>
</taskBody>

Media Service的识别分析服务非常强大,它还包含了移动侦测、人脸识别、表情识别等等。

https://azure.microsoft.com/zh-cn/documentation/articles/media-services-analytics-overview/

转载于:https://www.cnblogs.com/wing-ms/p/5806785.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于JavaMediaPlayer在线播放代码示例: ```java import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.media.ControllerEvent; import javax.media.ControllerListener; import javax.media.EndOfMediaEvent; import javax.media.Manager; import javax.media.NoPlayerException; import javax.media.Player; import javax.media.Time; public class MediaPlayerExample extends JPanel implements ControllerListener { private static final long serialVersionUID = 1L; private Player player; private Component video; private Component control; public MediaPlayerExample() { try { setPreferredSize(new Dimension(640, 360)); setLayout(new BorderLayout()); URL url = new URL("http://example.com/video.mp4"); player = Manager.createPlayer(url); player.addControllerListener(this); player.realize(); video = player.getVisualComponent(); if (video != null) { add(video, BorderLayout.CENTER); } control = player.getControlPanelComponent(); if (control != null) { add(control, BorderLayout.SOUTH); } } catch (MalformedURLException e) { System.err.println("Invalid media URL: " + e); } catch (NoPlayerException e) { System.err.println("Failed to create media player: " + e); } catch (IOException e) { System.err.println("Failed to initialize media player: " + e); } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame frame = new JFrame("MediaPlayer Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new MediaPlayerExample()); frame.pack(); frame.setVisible(true); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } }); } public void controllerUpdate(ControllerEvent event) { if (event.getSource() == player && event instanceof EndOfMediaEvent) { player.setMediaTime(new Time(0)); player.start(); } } } ``` 在这个示例中,我们使用Java的`javax.media`包来实现MediaPlayer在线播放。在构造方法中,我们初始化了一个URL对象,用于指定视频文件的URL。然后,我们使用Manager.createPlayer()方法创建一个Player对象,并将其添加为ControllerListener,以便在播放状态发生变化时接收通知。接着,我们调用Player.realize()方法来准备播放器,并获取视频组件和控制面板组件,并将它们添加到面板中。 在main()方法中,我们使用SwingUtilities.invokeLater()方法来在事件分派线程中创建并显示GUI。在windowClosing()方法中,我们调用System.exit()方法来退出程序。 在controllerUpdate()方法中,我们检查事件源是否为Player,并且事件类型是否为EndOfMediaEvent。如果是,我们将媒体时间设置为0,然后重新开始播放。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值