Open msi008 opened 8 years ago
Please check the documentation:
Hi muaz khan, Very nice work!!
I tested this procedure and I have a problem to display the "video-container" with android 4.4.x and iOS, maybe I missed something.
This is the code that i use for Append the 'Video-Container" to the page
var videosContainer = document.getElementById('videos-container');
connection.onstream = function(event) {
videosContainer.appendChild(event.mediaElement);
setTimeout(function() {
event.mediaElement.play();
}, 5000);
};
RTCMultiConnection v3.2.97 Results :
Here log of connection when "video-container" is not display:
info - socket.io started Server listening at 0.0.0.0:9001 debug - served static content /socket.io.js debug - client authorized info - handshake authorized YnFiLfE4ZTDL0p1QvZZM debug - setting request GET /socket.io/1/websocket/YnFiLfE4ZTDL0p1QvZZM?userid=emxdostt01kyb9&msgEvent=video-conference-demo&socketCustomEvent=RTCMultiConnection-Custom-Message debug - set heartbeat interval for client YnFiLfE4ZTDL0p1QvZZM debug - client authorized for debug - websocket writing 1:: { userid: 'emxdostt01kyb9', msgEvent: 'video-conference-demo', socketCustomEvent: 'RTCMultiConnection-Custom-Message', t: '1459428999137' } debug - sending data ack packet debug - websocket writing 6:::1+[false,"1"]
Android 4.4 Log :
"Uncaught TypeError: Cannot call method 'getUserMedia' of undefined", source: file:///android_asset/www/js/index.js (48)
HI @muaz-khan
Emulator Nexus_5X_API_22 Android 5.1.1.
.
Please help me how I can fix it? Thanks!
@NguyenTungs Can you try following app on your Android and see if it works?
To test it:
Hi @muaz-khan. Thank you for your answer! i test and very nice work! But In my case it seems to lack a library. Code I'm here! Please tell me where I'm wrong config. Here ios nice work. Thank you!
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>Demo for Muaz-Khan</title>
</head>
<body>
<section class="experiment">
<div class="make-center">
<input type="text" id="broadcast-id" placeholder="broadcast-id" value="sontung">
<button id="open-or-join">Open or Join Broadcast</button>
</div>
<video id="video-preview" controls loop></video>
</section>
<script type="text/javascript" src="https://rtcmulticonnection.herokuapp.com/socket.io/socket.io.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', function() {
// ......................................................
// ..................LIB RTC3 HERE.............
// ......................................................
// ......................................................
// ..................RTCMultiConnection Code.............
// ......................................................
var enableRecordings = false;
var connection = new RTCMultiConnection(null, {
useDefaultDevices: true // if we don't need to force selection of specific devices
});
connection.userid = 'NGUYEN-TUNG';
connection.enableScalableBroadcast = true;
connection.maxRelayLimitPerUser = 2;
connection.autoCloseEntireSession = true;
connection.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/';
connection.socketMessageEvent = 'scalable-media-broadcast-demo';
connection.connectSocket(function(socket) {
socket.on('join-broadcaster', function(hintsToJoinBroadcast) {
console.log('join-broadcaster====', hintsToJoinBroadcast);
connection.session = hintsToJoinBroadcast.typeOfStreams;
connection.sdpConstraints.mandatory = {
OfferToReceiveVideo: !!connection.session.video,
OfferToReceiveAudio: !!connection.session.audio
};
console.log(hintsToJoinBroadcast.userid);
connection.join(hintsToJoinBroadcast.userid);
});
});
var broadcastId = 'sontung';
//var demo = document.getElementById('open-or-join');
$(document).ready(function() {
$('#open-or-join').on('touchstart', function(e) {
console.log(broadcastId);
connection.session = {
audio: true,
video: true,
oneway: true
};
var socket = connection.getSocket();
socket.emit('check-broadcast-presence', broadcastId, function(isBroadcastExists) {
if (!isBroadcastExists) {
// the first person (i.e. real-broadcaster) MUST set his user-id
connection.userid = broadcastId;
}
console.log('check-broadcast-presence', broadcastId, isBroadcastExists);
connection.userid = 'NGUYEN-TUNG';
socket.emit('join-broadcast', {
broadcastId: broadcastId,
userid: connection.userid,
typeOfStreams: connection.session
});
});
});
});
var videoPreview = document.getElementById('video-preview');
connection.onstream = function(event) {
if (connection.isInitiator && event.type !== 'local') {
return;
}
if (event.mediaElement) {
event.mediaElement.pause();
delete event.mediaElement;
}
connection.isUpperUserLeft = false;
videoPreview.src = URL.createObjectURL(event.stream);
videoPreview.play();
videoPreview.userid = event.userid;
if (event.type === 'local') {
videoPreview.muted = true;
}
}
});
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
app.initialize();
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" package="org.mobileApp" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name" android:supportsRtl="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
</manifest>
<?xml version='1.0' encoding='utf-8'?>
<widget id="org.mobileApp" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>mobileApp</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</description>
<author email="dev@cordova.apache.org" href="http://cordova.io">
Apache Cordova Team
</author>
<content src="index.html" />
<plugin name="cordova-plugin-whitelist" spec="1" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<hook type="after_platform_add" src="hooks/iosrtc-swift-support.js" />
<config-file target="*-Info.plist" parent="CFBundleURLTypes">
<array>
<key>NSAppTransportSecurity</key>
<dict><key>NSAllowsArbitraryLoads</key><true/></dict>
</array>
</config-file>
</platform>
<preference name="xwalkVersion" value="16+" />
<preference name="xwalkCommandLine" value="--disable-pull-to-refresh-effect --allow-file-access-from-files --disable-web-security" />
<preference name="xwalkMode" value="embedded" />
<preference name="xwalkMultipleApk" value="true" />
<preference name="BackgroundColor" value="0xFFFF0000" />
<preference name="xwalkUserAgent" value="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36" />
<preference name="AndroidPersistentFileLocation" value="Internal" />
</widget>
Please tell me where I'm wrong config. Here ios nice work. Thank you!
Please make sure to link script-files from local directory:
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/socket.io.js"></script>
<script type="text/javascript" src="js/index.js"></script>
Your config.xml
file must allow requests from your domain:
<content src="index.html" />
<access origin="*" subdomains="true" uri="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<allow-navigation href="https://*/*" />
<platform name="android">
<allow-navigation href="https://rtcmulticonnection.herokuapp.com/*" />
<allow-intent href="https://rtcmulticonnection.herokuapp.com/*" />
<access origin="https://rtcmulticonnection.herokuapp.com" />
</platform>
Make sure you have this plugin installed:
AndroidManifest.xml
should look like this:
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="1" android:versionName="0.0.1" package="com.yourname" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:hardwareAccelerated="true" android:icon="@drawable/icon" android:label="@string/app_name" android:supportsRtl="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MICROPHONE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest>
Please try above codes, and if possible share errors as well.
Please add following code on TOP of your index.js
file:
window.onerror = function(message, source, lineno, colno, error) {
message += '\n';
message += 'Line No. ' + lineno;
message += '\n';
message += 'Col No. ' + colno;
if (error) {
message += '\n';
message += 'Error. ' + error;
}
if (source) {
message += '\n';
message += 'Source. ' + source;
}
if (message.indexOf('An attempt was made to use an object that is not') !== -1) {
return;
}
alert(message);
};
This will help you debug & fix issues.
You can even extend above error-logs:
console.error = function() {
window.onerror( JSON.stringify(arguments), '', 0, 0, '');
};
// as well as
console.log = console.info = console.debug = console.warn = function() {
document.write(JSON.stringify(arguments, null, '<br>') + '<hr>');
};
Hi @muaz-khan !
The first, thank you for your answer!
Very nice work!
HI @muaz-khan
Device: Xiaomi Redmi Note 2_API_21 Android 5.0.1.
Hi i want to use my own server instead of https://rtcmulticonnection.herokuapp.com:443/. in Cordova App Currenlty my server script is
// Muaz Khan - www.MuazKhan.com // MIT License - www.WebRTC-Experiment.com/licence // Source Code - https://github.com/muaz-khan/WebRTC-Scalable-Broadcast
var isUseHTTPs = true && !(!!process.env.PORT || !!process.env.IP); var fs = require("fs"); var path = require('path');
var server = require(isUseHTTPs ? 'https' : 'http');
function serverHandler(request, response) { var uri = require('url').parse(request.url).pathname, filename = path.join(process.cwd(), uri);
var isWin = !!process.platform.match(/^win/);
if (fs.statSync(filename).isDirectory()) {
if(!isWin) filename += '/index.html';
else filename += '\\index.html';
}
fs.exists(filename, function (exists) {
if (!exists) {
response.writeHead(404, {
"Content-Type": "text/plain"
});
response.write('404 Not Found: ' + filename + '\n');
response.end();
return;
}
fs.readFile(filename, 'binary', function (err, file) {
if (err) {
response.writeHead(500, {
"Content-Type": "text/plain"
});
response.write(err + "\n");
response.end();
return;
}
response.writeHead(200);
response.write(file, 'binary');
response.end();
});
});
}; var app; if (isUseHTTPs) {
var options = {
key: fs.readFileSync(path.join(__dirname, 'fake-keys/privatekey.pem')),
cert: fs.readFileSync(path.join(__dirname, 'fake-keys/certificate.pem'))
};
app = server.createServer(options, serverHandler);
} else app = server.createServer(serverHandler);
app = app.listen(process.env.PORT || 8888, process.env.IP || "192.168.10.11", function() { var addr = app.address(); console.log("Server listening at", addr.address + ":" + addr.port); });
require('./WebRTC-Scalable-Broadcast.js')(app); But when i use app and click button to start stream, nothing happens even server is not receiving request
hi,muaz-khan, google play shareFile app is not link,Where can I download it,i want to work on android and ios communicate