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

相关文章

Python+FFmpeg实现视频自动化处理的完整指南

《Python+FFmpeg实现视频自动化处理的完整指南》本文总结了一套在Python中使用subprocess.run调用FFmpeg进行视频自动化处理的解决方案,涵盖了跨平台硬件加速、中间素材处理... 目录一、 跨平台硬件加速:统一接口设计1. 核心映射逻辑2. python 实现代码二、 中间素材处

MySQL中between and的基本用法、范围查询示例详解

《MySQL中betweenand的基本用法、范围查询示例详解》BETWEENAND操作符在MySQL中用于选择在两个值之间的数据,包括边界值,它支持数值和日期类型,示例展示了如何使用BETWEEN... 目录一、between and语法二、使用示例2.1、betwphpeen and数值查询2.2、be

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)

《JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)》:本文主要介绍如何在IntelliJIDEA2020.1中创建和部署一个JavaWeb项目,包括创建项目、配置Tomcat服务... 目录简介:一、创建项目二、tomcat部署1、将tomcat解压在一个自己找得到路径2、在idea中添加

Java利用Spire.Doc for Java实现在模板的基础上创建Word文档

《Java利用Spire.DocforJava实现在模板的基础上创建Word文档》在日常开发中,我们经常需要根据特定数据动态生成Word文档,本文将深入探讨如何利用强大的Java库Spire.Do... 目录1. Spire.Doc for Java 库介绍与安装特点与优势Maven 依赖配置2. 通过替换

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

SpringBoot实现图形验证码的示例代码

《SpringBoot实现图形验证码的示例代码》验证码的实现方式有很多,可以由前端实现,也可以由后端进行实现,也有很多的插件和工具包可以使用,在这里,我们使用Hutool提供的小工具实现,本文介绍Sp... 目录项目创建前端代码实现约定前后端交互接口需求分析接口定义Hutool工具实现服务器端代码引入依赖获

C#中DateTime的格式符的实现示例

《C#中DateTime的格式符的实现示例》本文介绍了C#中DateTime格式符的使用方法,分为预定义格式和自定义格式两类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值... 目录DateTime的格式符1.核心概念2.预定义格式(快捷方案,直接复用)3.自定义格式(灵活可控