原文转自

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:biraj@192.168.5.85: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>
asked Jan 13 at 6:37
 
    
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 

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?

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

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

  1. 可在广域网部署运行的QQ高仿版 -- GG叽叽V3.0,完善基础功能(源码)

    (前段时间封闭式开发完了一个项目,最近才有时间继续更新GG的后续版本,对那些关注GG的朋友来说,真的是很抱歉.)GG的前面几个版本开发了一些比较高级的功能,像视频聊天.远程桌面.文件传送.远程磁盘等, ...

  2. 可在广域网部署运行的QQ高仿版 -- GG叽叽V1.8(源码)

    距离的GG 1.0发布已经三周了,这三周内,我利用业余时间为GG增加了视频聊天的功能.个人觉得进展有些缓慢,主要是因为大多数时间都花在了UI上.由于本人不会PS,所以图片素材都是从网上一个一个搜下来的 ...

  3. Maqetta源码运行

    一.Maqetta简介 Maqetta是IBM开发的一个创建桌面和移动用户界面的HTML5设计编辑工具.该项目已经捐助给开源机构Dojo基金会.Maqetta提供WYSIWYG可视化HTML5用户界面 ...

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

    作者 : 韩曙亮  博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csd ...

  5. 鸿蒙内核源码分析(信号消费篇) | 谁让CPU连续四次换栈运行 | 百篇博客分析OpenHarmony源码 | v49.04

    百篇博客系列篇.本篇为: v49.xx 鸿蒙内核源码分析(信号消费篇) | 谁让CPU连续四次换栈运行 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁 ...

  6. AirTest源码分析之运行器

    from: https://blog.csdn.net/u012897401/article/details/82900562 使用:根据airtest文档说明,可以通过命令行来启动air脚本,需要传 ...

  7. Tensorflow版Faster RCNN源码解析(TFFRCNN) (2)推断(测试)过程不使用RPN时代码运行流程

    本blog为github上CharlesShang/TFFRCNN版源码解析系列代码笔记第二篇   推断(测试)过程不使用RPN时代码运行流程 作者:Jiang Wu  原文见:https://hom ...

  8. 老李推荐:第5章1节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 官方简介

    老李推荐:第5章1节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 官方简介   在MonkeyRunner的框架中,Monkey是作为一个服务来接受来自Monkey ...

  9. 鸿蒙内核源码分析(用栈方式篇) | 程序运行场地谁提供的 | 百篇博客分析OpenHarmony源码 | v20.04

    百篇博客系列篇.本篇为: v20.xx 鸿蒙内核源码分析(用栈方式篇) | 程序运行场地谁提供的 | 51.c.h .o 精读内核源码就绕不过汇编语言,鸿蒙内核有6个汇编文件,读不懂它们就真的很难理解 ...

随机推荐

  1. SQL存储过程生成顺序编码

    一.第一种方式 USE [WJKC]GO/****** Object:  StoredProcedure [dbo].[Address_GetCode1]    Script Date: 2016/3 ...

  2. CSS3初学篇章_5(背景样式/列表样式/过渡动画)

    背景样式 1.背景颜色语法:background-color : transparent | color body { background-color:#CCCCCC;} 2.渐变色彩语法:back ...

  3. LaTex 文本排版

    一.对齐段落 \\ or \newline 另起一行,而不是另起一段 \\* 在强制断行后,还禁止分页 \newpage 另起一页 \linebreak[n] \nolinebreak[n] \pag ...

  4. window对象中的常见方法

    <body><!-- window对象中的常见方法--><script type="text/javascript"> var timeid; ...

  5. Windows下如何安装Python的第三方库

    有下面几个办法: 1. 通过http://www.lfd.uci.edu/~gohlke/pythonlibs/这个网站, 下载whl文件, 解压之后会有三个文件夹, 将最短名字的那个文件夹复制到C: ...

  6. 【iCore3 双核心板】例程十五:USB_CDC实验——高速数据传输

    实验指导书及代码包下载: http://pan.baidu.com/s/1gemYjz9 iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...

  7. Socket请求和Http请求的各自特点、区别及适用场景

    Socket实现服务器与客户端之间的物理连接,并进行数据传输.主要有TCP/UDP两个协议.Socket处于网络协议的传输层.TCP:传输控制协议,面向连接的的协议,稳定可靠.当客户和服务器彼此交换数 ...

  8. js树形控件

    js树形控件 ztree http://www.treejs.cn/

  9. QTP功能点笔记

    1.QTP启动应用程序的几种方法 1)用SystemUtil.Run 1 SystemUtil.Run "C:\Program Files (x86)\HP\QuickTest Profes ...

  10. Android RecyclerView的基本使用

    Android RecyclerView 在去年的Google I/O大会上就推出来了,以前经常使用的ListView 继承的是AbsListView,而RecyclerView则直接继承 ViewG ...