Kurento应用开发指南(以Kurento 5.0为模板) 之二:示例教程helloworld

本文主要是介绍Kurento应用开发指南(以Kurento 5.0为模板) 之二:示例教程helloworld,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

5. Kurento教程

这部分包含了如何使用Kurento框架的教程,以创建不同类型WebRTC和多媒体应用。
教程包含下面三个方面:
? Java: 
These show applications where clients interact with an application server based on Java EE technology. 
The application server hold the logic orchestrating the communication 
among the clients and controlling Kurento Server capabilities for them.

? Browser JavaScript: 
These show applications executing at the browser and communicating directly with the Kurento Media Server. 
In these tutorial, all the application logic is hold by the browser. Hence, no application
server is necessary. For these reasons, these applications need to be simple.

? Node.js: 
These show applications where clients interact with an application server based on Node.js technology. 
下面这个例子是使用Kurento创建的一个最简单的WebRTC应用。
它实现一个WebRTC回看(一个WebRTC媒体流从客户端发送到Kurento,然后再返回到客户端)。

5.1  Java 教程1 - Hello world

这个网页应用程序是为了给Java开发者介绍Kurento开发规则的。它包含一个基于WebRTC视频回看功能。

5.1.1 运行示例程序

在运行本示例前,需要先安装 Kurento Media Server,可见前面的安装指南。
另外,你还需要先在你的系统中安装 JDK (at least version 7), Maven, Git, 以及Bower。
Bower的可以使用npm(Node.js的包管理器)来安装。在Ubuntu机器上,它的安装命令如下:
# sudo apt-get install curl
# curl -sL https://deb.nodesource.com/setup | sudo bash -
# sudo apt-get install -y nodejs
# sudo npm install -g bower

为了加载这个应用程序,你需要先从GibHub项目上克隆,安装并运行主类,命令如下:
git clone https://github.com/Kurento/kurento-tutorial-java.git
# cd kurento-tutorial-java/kurento-hello-world
# mvn clean compile exec:java
程序启动后,就可用兼容WebRTC的浏览器(Chrom, Firefox),输入URL http://localhost:8080/ 来测试。

5.1.2 运行时的出错

运行命令mvn clean compile exec:java 时的出错处理
1. 错误提示:
[INFO] --------------------------------
[ERROR] No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal>or<plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. …

[ERROR]
[ERROR]  For more information about the errors and possible solution, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/NoGoalSpecifiedException

使用下面的命令追踪错误的更详细信息 
mvn –X 
解决办法:
详解解释见它的提示网页:
https://cwiki.apache.org/confluence/display/MAVEN/NoGoalSpecifiedException
在pom.xml文件中添加如下标签:
<project>
  ...
  <build>
        <defaultGoal>compile</defaultGoal>
    ...
  </build>
  ...
</project>


2. 错误提示
bower jquery#>= 1.9.1           cached git://github.com/jquery/jquery.git#2.1.4
bower jquery#>= 1.9.1         validate 2.1.4 against git://github.com/jquery/jquery.git#>= 1.9.1
bower                           EACCES EACCES, mkdir '/opt/kurento/kurento-tutorial-java/kurento-one2many-call/src/main/resources/static/bower_components'


Stack trace:
Error: EACCES, mkdir '/opt/kurento/kurento-tutorial-java/kurento-one2many-call/src/main/resources/static/bower_components'
    at Error (native)


Console trace:
Error
    at StandardRenderer.error (/usr/local/lib/node_modules/bower/lib/renderers/StandardRenderer.js:82:37)
    at Logger.<anonymous> (/usr/local/lib/node_modules/bower/bin/bower:110:22)
    at Logger.emit (events.js:109:17)
    at Logger.emit (/usr/local/lib/node_modules/bower/node_modules/bower-logger/lib/Logger.js:29:39)
    at /usr/local/lib/node_modules/bower/lib/commands/index.js:45:20
    at _rejected (/usr/local/lib/node_modules/bower/node_modules/q/q.js:844:24)
    at /usr/local/lib/node_modules/bower/node_modules/q/q.js:870:30
    at Promise.when (/usr/local/lib/node_modules/bower/node_modules/q/q.js:1122:31)
    at Promise.promise.promiseDispatch (/usr/local/lib/node_modules/bower/node_modules/q/q.js:788:41)
    at /usr/local/lib/node_modules/bower/node_modules/q/q.js:604:44
System info:
Bower version: 1.4.1
Node version: 0.13.0-pre
OS: Linux 3.16.0-23-generic x64
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.512s
[INFO] Finished at: Wed Jul 08 18:16:09 CST 2015
[INFO] Final Memory: 17M/457M
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (default) on project kurento-hello-world: Command execution failed. Process exited with an error: 1 (Exit value: 1) -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.3.2:exec (default) on project kurento-hello-world: Command execution failed.
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:217)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.MojoExecutionException: Command execution failed.
at org.codehaus.mojo.exec.ExecMojo.execute(ExecMojo.java:303)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
... 19 more
Caused by: org.apache.commons.exec.ExecuteException: Process exited with an error: 1 (Exit value: 1)
at org.apache.commons.exec.DefaultExecutor.executeInternal(DefaultExecutor.java:402)
at org.apache.commons.exec.DefaultExecutor.execute(DefaultExecutor.java:164)
at org.codehaus.mojo.exec.ExecMojo.executeCommandLine(ExecMojo.java:746)
at org.codehaus.mojo.exec.ExecMojo.execute(ExecMojo.java:292)
... 21 more
[ERROR] 
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException


解决方案:
是因为这句话:
Error: EACCES, mkdir '/opt/kurento/kurento-tutorial-java/kurento-one2many-call/src/main/resources/static/bower_components'
它在编译过程中会要创建和删除目录及文件,因为文件夹的权限不对,所以导致的这个错误。
使用命令更改文件夹的权限:
$ sudo chown username –R kurento-hello-world 
$ sudo chmod +777 kurento-hello-world

5.1.3 示例程序的分析

Kurento提供给开发者一个 Kurento Java客户端来控制 Kurento Media Server。
这个客户端库可以被任何Java应用程序使用,如Server Side Web, Desktop, Android等。
它也兼容所有像JavaEE,Spring, Play, Vert.x, 和JavaFx框架。

这个Hello world的DEMO是Kurento最简单的Web应用,下面的图片是这个DEMO运行时的截图。
 
Figure 6.1: Kurento Hello World Screenshot: WebRTC in loopback

这个应用程序的接口(一个HTML页面)是由两个HTML5标签组成的: 
一个用来显示本地视频流(由摄像头捕捉到的);
另一个用来显示由媒体服务器发送给客户端的远端视频流。


这个应用程序的逻辑很简单:
将本地流发送到Kurento Media Server,它不对流做任何修改直接返回给客户端。
为了实现这个逻辑,我们需要创建一个由单个Media Element组成的Media Pipeline。
Media Element可以是WebRtcEndpoint, 它具有WebRTC媒体流的全双向数据交换能力。
这个媒体元素和它自己连接,因此,它的在浏览器接收到的媒体是从浏览器发送出去的。
这个媒体管道的示例图如下:


这个页面应用程序同样的客户-服务端架构。
在客户端,它的逻辑是由JavaScript实现的。
  在服务端,我们使用了Java应用程序服务器来消费Kurento Java Client API对Kurento Media Server能力的控制。
总之,这个示例的高级架构是三层。
为了实现实体间的通信使用了下面的技术:
? REST: 用于在JavaScript客户端和Java应用程序的服务端进行通信。
? WebSocket: 用于在 Kurento Java客户端和 Kurento Media Server间进行通信。
这个通信是由Kurento协议实现的。更多细节见协议文档
 
Figure 6.2: Kurento Hello World Media Pipeline in context


下面的时序图显示了三个应用程序接口层的交互时序:
i) JavaScript logic; 
ii) Application server logic (which uses the Kurento Java Client);
iii) Kurento Media Server


Note: 客户和服务端的通信可以不需要REST,为了简单化,在这个DEMO中使用了REST。
在后面的例子中,客户和服务端使用了更复杂的信令通信机制,WebSockets。


The following sections analyze in deep the server (Java) and client-side (JavaScript) 
code of this application. The complete source code can be found in GitHub.
下面的章节深度分析了这个DEMO的服务端(Java)和客户端(JavaScript)的代码。完整的源码可以从GitHub上下载。


5.1.4 应用程序服务端逻辑
这个DEMO在服务端使用了Java的Spring Boot框架,这个技术可以被嵌入到Tomcat网页服务器中使用,从而简化了开发进程。
Note: You can use whatever Java server side technology you prefer to build web applications with Kurento.
For example, a pure Java EE application, SIP Servlets, Play, Vert.x, etc. 
Here we chose Spring Boot for convenience.


在下面的示图中,可以看到服务端代码的类图。
这个DEMO的主类是HelloWorldApp, 如代码中所见,KurentoClient是Spring Bean的实例。
这个组件用来创建Kurento Media Pipelines, 它用来给应用程序添加媒体的能力。
在这个实例中,我们可以看到需要对客户端库指定Kurento Media Server的位置。
在这个示例中,我们假定它位于本机的8888端口。如果你要重构这个DEMO,你需要自已指定你的Kurento Media Server 实例的位置。


当Kurento Client被实例化后,就可以准备和Kurento Media Server通信并控制它的媒体能力。
 
Figure 6.3: Complete sequence diagram of Kurento Hello World (WebRTC in loopbak) demo


Figure 6.4: Server-side class diagram of the HelloWorld app
 
@ComponentScan
@EnableAutoConfiguration
public class HelloWorldApp {
       @Bean
       public KurentoClient kurentoClient() {
              return KurentoClient.create("ws://localhost:8888/kurento");
       }
       public static void main(String[] args) throws Exception {
              new SpringApplication(HelloWorldApp.class).run(args);
       }
}


如前所述,我们使用了REST进行客户端与Java应用程序服务端的通信。
特别的,我们在服务端使用Spring声明 @RestController来实现REST服务。
下面来看HelloWorld-Controller类:
@RestController
public class HelloWorldController {
       @Autowired
       private KurentoClient kurento;


       @RequestMapping(value = "/helloworld", method = RequestMethod.POST)
       private String processRequest(@RequestBody String sdpOffer)
       throws IOException {
              // Media Logic
              MediaPipeline pipeline = kurento.createMediaPipeline();
              WebRtcEndpoint webRtcEndpoint = new WebRtcEndpoint.Builder(pipeline).build();
              webRtcEndpoint.connect(webRtcEndpoint);


              // SDP negotiation (offer and answer)
              String responseSdp = webRtcEndpoint.processOffer(sdpOffer);
              return responseSdp;
       }
}


应用程序逻辑是在processRequest方法中实现的。
POST请求将路径 /helloworld 发送出去,它主要执行两个部分:
? 配置媒体处理逻辑: 
在应用程序中,这个部分配置了Kurento如何来处理媒体。换句话说,是在这里创建了媒体管道。
为了这个目的,对象KurentoClient用来创建一个MediaPipeline对象,通过它,我们所需要的媒体元素被创建并连接。
在这个例子中,我们只需要初始化一个WebRtcEndpoint来接收WebRTC流,然后再把它发回给客户端。


? WebRTC SDP 协商: 
在WebRTC中,SDP (Session Description protocol) 用来在App间进行媒体数据交换的协商。
这种协商的发生是基于SDP提交和回答的交换机制。
在这个例子中,我们假设SDP的提交和回答包含了所有WebRTC ICE候选者。
这个协商是在 processRequest 方法的第二部分实现的,在浏览器客户端使用了SDP提交,
然后由WebRtcEndPoint生成一个SDP回答并返回。


5.1.5  客户端逻辑

接着来看客户端的应用程序,它是一个单页面应用程序框架(SPA)。
为了呼叫前面创建REST服务,我们使用了JavaScript库jQuery。
另外,我们使用了Kurento JavaScript 应用库,叫做Kurento-utils.js,来简化浏览器中WebRTC的管理。
这个库依赖于adapter.js,它是一个JavaScript WebRTC应用,由Google管理,它抽象了浏览器的差异。
最后这个应用程序也需要jquery.js。


These libraries are linked in the index.html web page, and are used in the index.js. 
In the start function we can see how jQuery is used to send a POST request to the path /helloworld, 
where the application server REST service is listening. 
The function WebRtcPeer.startSendRecv abstracts the WebRTC internal details (i.e. PeerConnection and getUserStream)
 and makes possible to start a full-duplexWebRTC communication, using the HTML video tag with id videoInput to 
show the video camera (local stream) and the video tag videoOutput to show the remote stream provided by the Kurento Media Server.


var webRtcPeer;
function start() {
       console.log("Starting video call ...");
       showSpinner(videoInput, videoOutput);
       webRtcPeer =
              kurentoUtils.WebRtcPeer.startSendRecv(videoInput, videoOutput, onOffer, onError);
}


function onOffer(sdpOffer) {
       console.info('Invoking SDP offer callback function ' + location.host);
       $.ajax({    
              url : location.protocol + '/helloworld',
              type : 'POST',
            dataType : 'text',
            contentType : 'application/sdp',
            data : sdpOffer,
            success : function(sdpAnswer) {
            console.log("Received sdpAnswer from server. Processing ...");
            webRtcPeer.processSdpAnswer(sdpAnswer);
    },
       error : function(jqXHR, textStatus, error) {
      onError(error);
    }
});
}
function onError(error) {
    console.error(error);
}


5.1.6 依赖库

This Java Spring application is implemented using Maven. 
The relevant part of the pom.xml is where Kurento dependencies are declared. 
As the following snippet shows, we need two dependencies: the Kurento Client Java dependency 
(kurento-client) and the JavaScript Kurento utility library (kurento-utils) for the client-side:
<dependencies>  
<dependency>
    <groupId>org.kurento</groupId>
    <artifactId>kurento-client</artifactId>
    <version>[5.0.0,6.0.0)</version>
  </dependency>
  <dependency>
    <groupId>org.kurento</groupId>
    <artifactId>kurento-utils-js</artifactId>
    <version>[5.0.0,6.0.0)</version>
  </dependency>
</dependencies>


Kurento framework uses Semantic Versioning for releases.
Notice that range [5.0.0,6.0.0) downloads the latest version of Kurento artefacts 
from Maven Central in version 5 (i.e. 5.x.x). Major versions are released when incompatible changes are made.
Note: We are in active development. You can find the latest version of Kurento Java Client at Maven Central. 


Kurento Java Client has a minimum requirement of Java 7. 
Hence, you need to include the following in the properties section:
<maven.compiler.target>1.7</maven.compiler.target>
<maven.compiler.source>1.7</maven.compiler.source>

这篇关于Kurento应用开发指南(以Kurento 5.0为模板) 之二:示例教程helloworld的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1093872

相关文章

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

SpringBoot整合OpenFeign的完整指南

《SpringBoot整合OpenFeign的完整指南》OpenFeign是由Netflix开发的一个声明式Web服务客户端,它使得编写HTTP客户端变得更加简单,本文为大家介绍了SpringBoot... 目录什么是OpenFeign环境准备创建 Spring Boot 项目添加依赖启用 OpenFeig

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

pandas中位数填充空值的实现示例

《pandas中位数填充空值的实现示例》中位数填充是一种简单而有效的方法,用于填充数据集中缺失的值,本文就来介绍一下pandas中位数填充空值的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是中位数填充?为什么选择中位数填充?示例数据结果分析完整代码总结在数据分析和机器学习过程中,处理缺失数

Pandas统计每行数据中的空值的方法示例

《Pandas统计每行数据中的空值的方法示例》处理缺失数据(NaN值)是一个非常常见的问题,本文主要介绍了Pandas统计每行数据中的空值的方法示例,具有一定的参考价值,感兴趣的可以了解一下... 目录什么是空值?为什么要统计空值?准备工作创建示例数据统计每行空值数量进一步分析www.chinasem.cn处

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合