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/

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

  1. 利用Azure Media Services Explorer发布VOD视频

    1.连接Media Services账号, 填入Media Services的账号以及Account Key 如果使用中国的Azure的话,需要在Endpoint节上更改一下,因为国内的Azure的接 ...

  2. 【Azure Developer】使用Java SDK代码创建Azure VM (包含设置NSG,及添加数据磁盘SSD)

    在参考Azure官方文档进行VM创建时,发现其中没有包含如何设置NSG的内容,以及如何在创建时就添加数据磁盘的代码(设置磁盘为SSD类型).本文的内容以"使用 Java 创建和管理 Azur ...

  3. 利用回调实现Java的异步调用

    异步是指调用发出后,调用者不会立刻得到结果,而是在调用发出后,被调用者通知调用者,或通过回调函数处理这个调用. 回调简单地说就是B中有一个A,这样A在调用B的某个方法时实际上是调用到了自己的方法. 利 ...

  4. 手把手:使用service principal连接Azure Media Service

    在简书中查看,请点击我. 关于相关内容解释,请参考docs文档 https://docs.microsoft.com/en-us/azure/media-services/previous/media ...

  5. Android(java)学习笔记229:服务(service)之绑定服务调用服务里面的方法 (采用接口隐藏代码内部实现)

    1.接口 接口可以隐藏代码内部的细节,只暴露程序员想暴露的方法 2.利用上面的思想优化之前的案例:服务(service)之绑定服务调用服务里面的方法,如下: (1)这里MainActivity.jav ...

  6. Android(java)学习笔记172:服务(service)之绑定服务调用服务里面的方法 (采用接口隐藏代码内部实现)

    1. 接口 接口可以隐藏代码内部的细节,只暴露程序员想暴露的方法 2. 利用上面的思想优化之前的案例:服务(service)之绑定服务调用服务里面的方法,如下: (1)这里MainActivity.j ...

  7. 解决Java调用Azure SDK证书错误javax.net.ssl.SSLHandshakeException

    Azure作为微软的公有云平台,提供了非常丰富的SDK和API让开发人员可以非常方便的调用的各项服务,目前除了自家的.NET, Java, Python, nodeJS, Ruby,PHP等语言都提供 ...

  8. Spring MVC普通类或工具类中调用service报空空指针的解决办法(调用service报java.lang.NullPointerException)

    当我们在非Controller类中应用service的方法是会报空指针,如图: 这是因为Spring MVC普通类或工具类中调用service报空null的解决办法(调用service报java.la ...

  9. 解决 Java 调用 Azure SDK 证书错误 javax.net.ssl.SSLHandshakeException

    Azure 作为微软的公有云平台,提供了非常丰富的 SDK 和 API 让开发人员可以非常方便的调用的各项服务,目前除了自家的 .NET.Java.Python. nodeJS.Ruby,PHP 等语 ...

随机推荐

  1. css选择器,用来处理隔行变色的表格

    CSS3 :nth-last-child() 选择器,可以用来处理隔行变色的表格,详情请参考网上资料.

  2. ntp.conf:很少有人提及的事

    [你可以到ntp.org下个ntp server的源代码,里面有HTML格式的文档,内容很全面.] [REF: http://doc.ntp.org/] Comprehensive List of C ...

  3. "aa".equals(name)这种写法为什么就可以避免空指针

    public static void main(String[] args) { String name=null; if("aa".equals(name))//这种情形,不出现 ...

  4. c# 甘蔗斗地主1.4存档修改器

           using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat ...

  5. SparkSql官方文档中文翻译(java版本)

    1 概述(Overview) 2 DataFrames 2.1 入口:SQLContext(Starting Point: SQLContext) 2.2 创建DataFrames(Creating ...

  6. Codeforces Round #369 (Div. 2) C. Coloring Trees(dp)

    Coloring Trees Problem Description: ZS the Coder and Chris the Baboon has arrived at Udayland! They ...

  7. purple-class2-默认选项切换

    ylbtech-class:purple-class2 A, 返回顶部 1,默认选项切换 #region 默认选项切换 public delegate IList<SelectListItemI ...

  8. 保持UIImagePickerController后导航栏风格统一

    1. UIImagePickerController 状态栏始终保持某一种风格. -(void)navigationController:(UINavigationController *)navig ...

  9. Python快速教程

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 怎么能快速地掌握Python?这是和朋友闲聊时谈起的问题. Python包含的内容 ...

  10. 拥抱 Android Studio 之五:Gradle 插件开发

    实践出真知 笔者有位朋友,每次新学一门语言,都会用来写一个贪吃蛇游戏,以此来检验自己学习的成果.笔者也有类似体会.所谓纸上得来终觉浅,绝知此事要躬行.这一章,笔者将以开发和发布一个 Gradle 插件 ...