如何使官方提供的AppRTCDemo 运行在自己搭建的server(官方提供的apprtc)上(官方的server源码)

原文转自

http://stackoverflow.com/questions/21085261/apprtcdemo-with-local-server-works-between-browsers-but-not-android-native-to-br

I am developing a chat application and done with it. Now I want to implement video chat also. After research a lot I decided to go with "WebRTC" library.

What I have done?

1) Able to run AppRtcDemo at local server and Its working fine between browsers.

Reference : http://www.webrtc.org/reference/getting-started

2) Able to build Android AppRtcDemo.But when I run it say "Cross origin does not support".

After research I found in webrtc discussion that to resolve this issue I need to set-up own turn server.

3) So I install latest rfc5766TurnServer recommended by webrtc. I got success to run turn server.

Reference : http://code.google.com/p/rfc5766-turn-server/

I do following changes to ApprtcDemo (web) and (Android) to work with my Turn server

1) apprtc.py

Replace:

turn_url = ‘https://computeengineondemand.appspot.com/‘
turn_url = turn_url + ‘turn?‘ + ‘username=‘ + user + ‘&key=4080218913‘

With point to my turn server:

turn_url = ‘http://192.168.5.85:3478/?service=turn&username=biraj‘

2) index.html

Replace:

var pcConfig = {{ pc_config|safe }};

With:

var pcConfig = {"iceServers": [{"url": "stun:stun.l.google.com:19302"},            {"url":"turn:[email protected]:3479", "credential":"0x5b04123c3eec4cf0be64ab909bb2ff5b"}]};

Android

1)AppRTCDemoActivity.java

Replace:

roomInput.setText("https://apprtc.appspot.com/?r=");

With my local apprtc server:

roomInput.setText("http://192.168.5.86:8080/?r=");

2) AppRTCClient.java

In private PeerConnection.IceServer requestTurnServer(String url){} function

Replace:

connection.addRequestProperty("origin", "https://apprtc.appspot.com");

With:

connection.addRequestProperty("origin", "http://192.168.5.86:8080");

3) /assets/channel.html

Replace:

<script src="https://apprtc.appspot.com/_ah/channel/jsapi"></script>

With:

<script src="http://192.168.5.86:8080/_ah/channel/jsapi"></script>

Now my question is why this is working between browsers but not between android AppRtcDemo and browser.

When I run AppRtcDemo on android after doing above changes local camera preview is started at right-top corner and message prompt "waiting for ICEcandidates" then nothing happens.

Thanks in advance.

Thanks to All for supporting my question.After long rocky ride with ApprtcDemo I got success and it works fine.I am posting the solution.

Find the "GAEChannelClient.java" java file.

and do change as below.

/*
 * libjingle
 * Copyright 2013, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS‘‘ AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.appspot.apprtc;

import java.io.InputStream;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.util.Log;
import android.webkit.ConsoleMessage;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;

/**
 * Java-land version of Google AppEngine‘s JavaScript Channel API:
 * https://developers.google.com/appengine/docs/python/channel/javascript
 *
 * Requires a hosted HTML page that opens the desired channel and dispatches JS
 * on{Open,Message,Close,Error}() events to a global object named
 * "androidMessageHandler".
 */
public class GAEChannelClient {
    private static final String TAG = "GAEChannelClient";
    private WebView webView;
    private final ProxyingMessageHandler proxyingMessageHandler;

    /**
     * Callback interface for messages delivered on the Google AppEngine
     * channel.
     *
     * Methods are guaranteed to be invoked on the UI thread of |activity|
     * passed to GAEChannelClient‘s constructor.
     */
    public interface MessageHandler {
        public void onOpen();

        public void onMessage(String data);

        public void onClose();

        public void onError(int code, String description);
    }

    /** Asynchronously open an AppEngine channel. */
    @SuppressLint("SetJavaScriptEnabled")
    public GAEChannelClient(Activity activity, String token, MessageHandler handler) {
        webView = new WebView(activity);

        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setAllowFileAccessFromFileURLs(true); // Maybe you
                                                                    // don‘t
                                                                    // need this
                                                                    // rule
        webView.getSettings().setAllowUniversalAccessFromFileURLs(true);

        webView.setWebChromeClient(new WebChromeClient() { // Purely for
                                                            // debugging.
            public boolean onConsoleMessage(ConsoleMessage msg) {
                Log.d(TAG, "console: " + msg.message() + " at " + msg.sourceId() + ":" + msg.lineNumber());
                return false;
            }
        });
        webView.setWebViewClient(new WebViewClient() { // Purely for debugging.
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Log.e(TAG, "JS error: " + errorCode + " in " + failingUrl + ", desc: " + description);
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                System.out.println("HI");
                return super.shouldOverrideUrlLoading(view, url);
            }
        });

        proxyingMessageHandler = new ProxyingMessageHandler(activity, handler, token);
        webView.addJavascriptInterface(proxyingMessageHandler, "androidMessageHandler");
//       webView.loadUrl("file:///android_asset/channel.html");
        try {
            InputStream is = activity.getAssets().open("channel.html");
            StringBuilder builder = new StringBuilder();
            byte[] buffer = new byte[1024];
            while (is.read(buffer) != -1) {
                builder.append(new String(buffer));
            }
            is.close();
            String str = builder.toString();
            webView.loadDataWithBaseURL("http://192.168.5.86:8080", str,"text/html","utf-8",null);}catch(Exception e){
            e.printStackTrace();}}/** Close the connection to the AppEngine channel. */publicvoid close(){if(webView ==null){return;}
        proxyingMessageHandler.disconnect();
        webView.removeJavascriptInterface("androidMessageHandler");
        webView.loadUrl("about:blank");
        webView =null;}// Helper class for proxying callbacks from the Java<->JS interaction// (private, background) thread to the Activity‘s UI thread.privatestaticclassProxyingMessageHandler{privatefinalActivity activity;privatefinalMessageHandler handler;privatefinalboolean[] disconnected ={false};privatefinalString token;publicProxyingMessageHandler(Activity activity,MessageHandler handler,String token){this.activity = activity;this.handler = handler;this.token = token;}publicvoid disconnect(){
            disconnected[0]=true;}privateboolean disconnected(){return disconnected[0];}@JavascriptInterfacepublicString getToken(){return token;}@JavascriptInterfacepublicvoid onOpen(){System.out.println("GAEClient : Open");
            activity.runOnUiThread(newRunnable(){publicvoid run(){if(!disconnected()){
                        handler.onOpen();}}});}@JavascriptInterfacepublicvoid onMessage(finalString data){System.out.println("GAEClient : Message : "+data );
            activity.runOnUiThread(newRunnable(){publicvoid run(){if(!disconnected()){
                        handler.onMessage(data);}}});}@JavascriptInterfacepublicvoid onClose(){System.out.println("GAEClient : Close");
            activity.runOnUiThread(newRunnable(){publicvoid run(){if(!disconnected()){
                        handler.onClose();}}});}@JavascriptInterfacepublicvoid onError(finalint code,finalString description){System.out.println("GAEClient : Erroe : "+ description);
            activity.runOnUiThread(newRunnable(){publicvoid run(){if(!disconnected()){
                        handler.onError(code, description);}}});}}}

Channel.html in assets folder

<html>
  <head>
    <script src="http://192.168.5.86:8080/_ah/channel/jsapi"></script>
  </head>
  <!--
  Helper HTML that redirects Google AppEngine‘s Channel API to a JS object named
  |androidMessageHandler|, which is expected to be injected into the WebView
  rendering this page by an Android app‘s class such as AppRTCClient.
  -->
  <body onbeforeunload="closeSocket()" onload="openSocket()">
    <script type="text/javascript">
      var token = androidMessageHandler.getToken();
      if (!token)
        throw "Missing/malformed token parameter: [" + token + "]";

      var channel = null;
      var socket = null;

      function openSocket() {
        channel = new goog.appengine.Channel(token);
        socket = channel.open({
          ‘onopen‘: function() { androidMessageHandler.onOpen(); },
          ‘onmessage‘: function(msg) { androidMessageHandler.onMessage(msg.data); },
          ‘onclose‘: function() { androidMessageHandler.onClose(); },
          ‘onerror‘: function(err) { androidMessageHandler.onError(err.code, err.description); }
        });
      }

      function closeSocket() {
        socket.close();
      }
    </script>
  </body>
</html>

android webrtc apprtcdemo rfc5766turnserver


share|improve this question

edited Jan 23 at 4:13

asked Jan 13 at 6:37

Biraj Zalavadia
8,3022726

 

    

Will you provide the logs during android and web communication. –  Ichigo Kurosaki Jan 18 at 8:01
    

@Biraj Zalavadia: like you have spend 1 month, i have lost 3 month still could not make it work, you mentioned your modification worked for you but i did exactly like you have shown which never worked for me. Could you please also join on my link here: stackoverflow.com/questions/23949237/… –  YumYumYum May 30 at 7:28
    

@hushao asks "[H]ow do you create you[r] local server? [Is it] the same [as] apprtc.appspot.com "? –  drs Jul 22 at 1:28 

add a comment

1 Answer

activeoldestvotes


up vote3down vote

+50

Sadly I don‘t know if you have done these things:

  1. Use the SAME stun and turn server on every application (wether PC or mobile).
  2. Are you even sending the ICE candidates between the applications (I think you do, but just to verify).
  3. Are you sure that the STUN/TURN url are the ones that give the error, as I can‘t believe that these things do about cross-origins (they shouldn‘t, as you are just connecting from a client to a server. Cross origin is mostly ‘used‘ on web pages that load data from an external source. You aren‘t allowed to do that from an XHR). I am really thinking it has something to do with https://apprtc.appspot.com/_ah/channel/jsapi, as this is a good example of cross origin stuff.

What if you open the web page that is working in your chrome browser on mobile? What does it do then? (note that you can connect your phone to your pc to have the full developer tools chrome has. Chrome runs on your android device but you can see the devtools on your pc).

If you can provide me these answers I might be able to help you. Try to revert all those changes and just use google‘s TURN server, but only make that https://apprtc.appspot.com/_ah/channel/jsapifile local.

EDIT: I see you found your answer. Would you mind to share it?


share|improve this answer

edited Jan 18 at 22:35

answered Jan 18 at 22:30

MarijnS95
1,7011118

 

    

I added the javascript inside the html file instead of loading via network. But still not working. Can you please help, nobody is sharing details who made it work. –  YumYumYum May 28 at 15:51
1  

@YumYumYum What exactly is not working? I have seen that the OP has found an answer but I have no idea what. –  MarijnS95 May 28 at 16:54
    

@MarjinS95: Actually what OP has reported here and on other url i have done exactly same + spend more then 1 month on it, and its not working like OP said it was. My problem is in AppRTCDemo when i execute to connect with local setup, it does not do anything after joining the room. if you want should i open a new question related to this and link you that please? I think you are the only person who understood this issue, most of all others are very confused. –  YumYumYum May 29 at 14:56
1  

@YumYumYum Opening a new question would be nice (you can add some more details, maybe even some logging about what functions are executed and what not). I am mainly a javascripter, no java‘er, so I have not that much knowledge about it but do understand most of it. I‘d also like to see some url‘s you are using to find out if you have any cross-origin problems too. –  MarijnS95 May 29 at 15:07
    

OK - i will do that, but i believe you can solve it. Most of the related issues were ignored by many other experts. But it think its more JavaScript related problem, i will create a new question about this with every details and step by step i took. Then inform you here today. Thanks a lot for your support, i really appreciate it. –  YumYumYum May 29 at 15:13

show 2 more comments

时间: 2024-10-29 19:53:03

如何使官方提供的AppRTCDemo 运行在自己搭建的server(官方提供的apprtc)上(官方的server源码)的相关文章

Docker环境下编译android源码|编译可运行xposed

前言 因为我的电脑是Ubuntu18的版本,成功编译xposed刷入手机之后无法启动,检查了所有的环境,没有问题,发现可能是Ubuntu系统的兼容库的问题,但是我不可能重新安装系统吧,毕竟有点蠢,所以最好的方式就是在docker的Ubuntu容器中编译,统一环境问题,也可以隔离环境平时 工作开发环境,下面开始操作 安装配置docker docker加速,采用对国人友好的镜像地址 通过修改daemon配置文件/etc/docker/daemon.json来使用加速器,执行以下命令: 您可以配置 D

【流媒体开发】VLC Media Player - Android 平台源码编译 与 二次开发详解 (提供详细800M下载好的编译源码及eclipse可调试播放器源码下载)

作者 : 韩曙亮  博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csdn.net/shulianghan VLC 二次开发 视频教程 : http://edu.csdn.net/course/detail/355 博客总结 : -- 本博客目的 : 让 Android 开发者通过看本博客能够掌握独立移植 VLC Media Player 核心框架到自己的 app 中,

转载:Pixhawk源码笔记十:代码调度,使之定时运行

转自:新浪长沙@WalkAnt 第十一部分 调用代码,使之定时运行 英文参考:http://dev.ardupilot.com/wiki/code-overview-scheduling-your-new-code-to-run-intermittently/ 本节源自:http://liung.github.io/blog/apm/2014-09-05-APM-ArduCopter规划新代码使之按一定频率运行.html 1.用代码调度器(scheduler)运行你的代码 在给定时间间隔内来运行

如果程序太大而不能在DOS下运行,怎样才能使它在DOS下运行呢?

如果你的程序因太大(超过640KB)而无法在DOS下运行,有两种办法可为该程序提供更多的内存.一种办法是使用覆盖管理程序(overlay manager).覆盖管理程序用来管理程序的模块,并根据需要把它们从磁盘中读入内存或从内存中删去.这样,即使你的程序有几兆字节那么大,仍然可以在 只有640KB可用内存的计算机上运行.一些高级的覆盖管理程序允许你对需要同时读入和删除的模块进行“编组”,这有助于你通过精心调整程序来改善它的性 能.其它一些稍差的覆盖管理程序不具备这种功能,因此使用它们时你无法通过

第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用(原创)

天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文"寻求合作伙伴编写<深入理解 MonkeyRunner>书籍".但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在所难免.有需要的就参考下吧,转发的话还请保留每篇文章结尾的出处等信息. 上一节我们描述了monkey的命令处理入口函数run是如何调用optionProcess方法来解析命令行参数的.启动参数主要时去指导Monkey时怎么运行起来的,但Monkey作为MonkeyRunner框架的一部分,

【转】在Ubuntu下编译Android源码并运行Emulator

原文网址:http://www.mcuos.com/thread-4553-1-1.html 建立编译环境 1.在VirtualBox上安装Ubuntu 2.安装JDK   $ sudo apt-get install sun-java5-jdk  或   $ sudo apt-get install sun-java6-jdk (donut 1.6)3.安装flex,bison,gperf,libsdl-dev,libesd0-dev,libwxgtk2.6-dev(可选),build-ess

【转】可在广域网部署运行的QQ高仿版 -- GG叽叽V3.4,增加系统设置、最近联系人、群功能(源码)

自从上次版本(GG叽叽V3.2,增加离线消息.离线文件功能)发布后,我个人觉得主要的大功能都实现得差不多了,接下来的几个版本将不断优化GG的细节,提高其可用性.这次版本更新的内容主要是为GG增加了系统设置.并完善的了群所需的基础功能. 一.GG V3.4 新增功能展现 1.群功能完善 (1)创建群 (2)退出群(同时,通知其它群成员) 2.系统设置 (1)叉掉主窗口时,关闭程序还是隐藏窗口. (2)麦克风设备索引 (3)摄像头设备索引 (4)开机自动启动 3.其它 (1)最近联系人列表. (2)

Java开发和运行环境的搭建

Java开发需要准备的东西? JDK+Eclipse 其中JDK的意思是Java开发工具包,Eclipse是进行用于做Java程序开发的工具(当然你也可以用记事本什么的去做). 其他开发工具:JCreator,JBuilder,... jdk的介绍和安装教程度娘里面到处都是,这里自己也在啰嗦一下吧. 关于jdk的详细介绍: JDK是Java Development Kit的缩写,即Java开发工具集.JDK是整个Java的核心,包括了Java运行环境(JRE).Java开发工具和Java基础类库

Jasperreport源码&demo运行

Jasperreport是著名的报表开源项目,提供了非常丰富的功能,可以满足日常开发中大部分的需求,下面将就该开源项目的demo运行做一些说明. 1.从sourceforge上下载jasperreport的工程http://sourceforge.net/projects/jasperreports/: 2.解压开,并导入eclipse/myeclipse,导入后的目录结构如下: 3.demo目录下为官方对应的示例,有三个目录,分别为hsql(内存数据库),font(字体)和samples(报表