我需要帮助,以查找有关如何将视频通话添加到应用程序的最新文档。我使用cordova和phonegap进行构建。另外,如果没有文档,请选择将视频通话添加到我的应用中。
我已经尝试过connectycube,optox。我唯一得到积极反馈并且几乎成功的是Quickblox,但样本已经3岁了,无法正常工作。
Quickblox,提醒我找不到麦克风或相机。我尝试给出权限,但错误仍然存在。
这是我的config.xml的代码,其中包含插件和权限。
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.phonegap.video" version="1.0.0"
xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0"
xmlns:android="http://schemas.android.com/apk/res/android">
<name>video</name>
<description>
Hello World sample application that responds to the deviceready event.
</description>
<author email="support@phonegap.com" href="http://phonegap.com">
PhoneGap Team
</author>
<content src="index.html" />
<preference name="DisallowOverscroll" value="true" />
<preference name="android-minSdkVersion" value="14" />
<plugin name="cordova-plugin-battery-status" source="npm" spec="~1.1.1" />
<plugin name="cordova-plugin-camera" source="npm" spec="~2.1.1" />
<plugin name="cordova-plugin-media-capture" source="npm" spec="~1.2.0" />
<plugin name="cordova-plugin-console" source="npm" spec="~1.0.2" />
<plugin name="cordova-plugin-contacts" source="npm" spec="~2.0.1" />
<plugin name="cordova-plugin-device" source="npm" spec="~1.1.1" />
<plugin name="cordova-plugin-device-motion" source="npm" spec="~1.2.0" />
<plugin name="cordova-plugin-device-orientation" source="npm"
spec="~1.0.2" />
<plugin name="cordova-plugin-dialogs" source="npm" spec="~1.2.0" />
<plugin name="cordova-plugin-file" source="npm" spec="~4.1.1" />
<plugin name="cordova-plugin-file-transfer" source="npm" spec="~1.5.0" />
<plugin name="cordova-plugin-geolocation" source="npm" spec="~2.1.0" />
<plugin name="cordova-plugin-globalization" source="npm" spec="~1.0.3" />
<plugin name="cordova-plugin-inappbrowser" source="npm" spec="~1.3.0" />
<plugin name="cordova-plugin-media" source="npm" spec="~2.2.0" />
<plugin name="cordova-plugin-network-information" source="npm"
spec="~1.2.0" />
<plugin name="cordova-plugin-splashscreen" source="npm" spec="~3.2.1" />
<plugin name="cordova-plugin-statusbar" source="npm" spec="~2.1.2" />
<plugin name="cordova-plugin-vibration" source="npm" spec="~2.1.0" />
<plugin name="cordova-plugin-whitelist" source="npm" spec="~1.2.1" />
<plugin spec="https://github.com/knowledgecode/WebSocket-for-Android"
source="git" />
<plugin spec="https://github.com/dpa99c/cordova-custom-config"
source="git" />
<plugin spec="https://github.com/BasqueVoIPMafia/cordova-plugin-iosrtc"
source="git" />
<platform name="android">
<icon density="xhdpi" src="www/res/icon/android/drawable-xhdpi-
icon.png" />
<icon density="xxhdpi" src="www/res/icon/android/drawable-xxhdpi-
icon.png" />
</platform>
<platform name="ios">
<icon height="57" platform="ios" src="www/res/icon/ios/icon.png"
width="57" />
</platform>
<platform name="wp8">
<icon height="99" platform="wp8" src="www/res/icon/wp8/ApplicationIcon.png" width="99" />
<icon height="159" platform="wp8" src="www/res/icon/wp8/Background.png" width="159" />
<splash height="1280" platform="wp8" src="www/res/screen/wp8/screen-portrait.jpg" width="768" />
</platform>
<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:*" />
<preference name="android-minSdkVersion" value="21" />
<preference name="android-targetSdkVersion" value="21" />
<config-file parent="/*" target="AndroidManifest.xml">
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"
/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
</config-file>
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<config-file platform="ios" target="*-Info.plist"
parent="NSCameraUsageDescription">
<string>Use camera for video calling</string>
</config-file>
<config-file platform="ios" target="*-Info.plist"
parent="NSMicrophoneUsageDescription">
<string>Use microphone for video calling</string>
</config-file>
</platform>
</widget>
这是我的index.html代码。在此处写有“错误:找不到设备(相机或麦克风)的警报。”的警报。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>QuickBlox JavaScript WebRTC sample</title>
<link rel="canonical" href="https://quickblox.github.io/quickblox-javascript-sdk/samples/webrtc" />
<link rel="shortcut icon" href="https://quickblox.com/favicon.ico">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css">
<!-- use http://una.im/CSSgram/ for filters -->
<link rel="stylesheet" href="https://cdn.rawgit.com/una/CSSgram/master/source/css/cssgram.css">
<!-- app styles -->
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="wrapper j-wrapper">
<header class="header">
<div class="inner">
<div class="header__logo">
<img class="header__logo_img" src="images/Logo_qb.svg"></img>
</div>
<h2 class="header__title">JavaScript WebRTC Sample</h2>
</div>
</header>
<main class="app" id="app">
<div class="page">
<!-- JOIN -->
<form class="join j-join">
<h3 class="join__title">
<p>Please enter your username and chat room name.</p>
<p>You can join existent chat room.</p>
<p class="join__notice">
Use several browsers to simulate several users.
</p>
</h3>
<div class="join__body">
<div class="join__row">
<input type="text" class="join__input" name="username" placeholder="Username" autofocus required title="Field should contain alphanumeric characters only in a range 3 to 20. The first character must be a letter." pattern="^[a-zA-Z][\w]{2,19}$">
</div>
<div class="join__row">
<input type="text" class="join__input" name="room" placeholder="Chat room name" required title="Field should contain alphanumeric characters only in a range 3 to 15, without space. The first character must be a letter." pattern="^[a-zA-Z][a-zA-Z0-9]{2,14}$">
</div>
<div class="join__row">
<button type="submit" class="join__btn">Login</button>
</div>
</div>
</form>
<div class="dashboard j-dashboard">
</div>
</div>
</main>
<footer class="footer j-footer invisible">
<h4>
<a class="fw-link" href="https://github.com/QuickBlox/quickblox-javascript-sdk/tree/gh-pages/samples/webrtc">
Source code
</a>
</h4>
</footer>
<!-- SOUNDS -->
<audio id="callingSignal" loop preload="auto">
<source src="audio/calling.ogg"></source>
<source src="audio/calling.mp3"></source>
</audio>
<audio id="ringtoneSignal" loop preload="auto">
<source src="audio/ringtone.ogg"></source>
<source src="audio/ringtone.mp3"></source>
</audio>
<audio id="endCallSignal" preload="auto">
<source src="audio/end_of_call.ogg"></source>
<source src="audio/end_of_call.mp3"></source>
</audio>
</div>
<!-- MODALS -->
<div class="modal fade" id="connect_err" tabindex="-1" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4>Connect to chat is failed</h4>
</div>
<div class="modal-body">
<p class="text-danger">
Something wrong with connect to chat. Check internet connection or user info and trying again.
</p>
</div>
<p></p>
</div>
</div>
</div>
<div class="modal fade" id="already_auth" tabindex="-1">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Warning</h4>
</div>
<div class="modal-body">
<p class="text-danger">User has already authorized.</p>
</div>
</div>
</div>
</div>
<div class="modal fade" id="error_no_calles" tabindex="-1">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Error</h4>
</div>
<div class="modal-body">
<p class="text-danger">Please choose users to call</p>
</div>
</div>
</div>
</div>
<div class="modal fade" id="income_call" tabindex="-1" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4>Call from <strong class="j-ic_initiator"></strong></h4>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default j-decline">Decline</button>
<button type="button" class="btn btn-primary j-accept">Accept</button>
</div>
</div>
</div>
</div>
<!-- TEMPLATES -->
<!-- stateBoard -->
<script type="text/template" id="tpl_default">
QuickBlox room is <b><%= tag %></b>. Logged in as <b><%= name %></b>
<button class='fw-link j-logout'>Logout</button>
</script>
<script type="text/template" id="tpl_during_call">
Login in as <b><%= name %></b>
</script>
<script type="text/template" id="tpl_device_not_found">
Error: devices (camera or microphone) are not found.
<span class="qb-text">Login in <b>as <%=name%></b></span>
<button class='fw-link j-logout'>Logout</button>
</script>
<script type="text/template" id="tpl_accept_call">
<% _.each(users, function(el, i, list) { %>
<% if(list.length === 1){ %>
<b><%= el.full_name %></b> has accepted the call
<% } else { %>
<% if( (i+1) === list.length) { %>
<b><%= el.full_name %></b> have accepted the call
<% } else { %>
<b><%= el.full_name %></b>,
<% } %>
<% } %>
<% }); %>
</script>
<script type="text/template" id="tpl_call_stop">
Call is stopped.  Login in as
<%=name%>
<button class='fw-link j-logout'>Logout</button>
</script>
<script type="text/template" id="p2p_call_stop">
<b><%=name%> has <%=reason%>.</b> Call is stopped.  Login in as
<%=currentName%>
<button class='fw-link j-logout'>Logout</button>
</script>
<script type="text/template" id="dashboard_tpl">
<div class="state_board j-state_board"></div>
<div class="dashboard__inner inner">
<div class="users j-users_wrap"></div>
<div class="board clearfix j-board"></div>
</div>
</script>
<script type="text/template" id="frames_tpl">
<div class="frames">
<div class="frames__main">
<div class="frames__main_timer invisible" id="timer">
</div>
<div class="qb-video">
<video id="main_video" class="frames__main_v qb-video_source"></video>
</div>
</div>
<div class="frames__callees j-callees"></div>
</div>
<div class="caller">
<div class="caller__ctrl">
<button class="caller__ctrl_btn j-actions"></button>
</div>
<h4 class="caller__name">
<b>You</b>
<span class="j-caller_name">(<%= nameUser %>)</span>
</h4>
<div class="caller__frames">
<div class="qb-video">
<video id="localVideo" class="qb-video_source"></video>
</div>
<div class="caller__frames_acts">
<button class="caller__frames_acts_btn j-caller__ctrl" data-target="video">
<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19" version="1.1">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-290.000000, -80.000000)">
<g transform="translate(288.000000, 78.000000)">
<path d="M0 0L24 0 24 24 0 24 0 0Z"/>
<path class="svg_icon" d="M21 6.5L17 10.5 17 7C17 6.45 16.55 6 16 6L9.82 6 21 17.18 21 6.5 21 6.5ZM3.27 2L2 3.27 4.73 6 4 6C3.45 6 3 6.45 3 7L3 17C3 17.55 3.45 18 4 18L16 18C16.21 18 16.39 17.92 16.54 17.82L19.73 21 21 19.73 3.27 2 3.27 2Z"/>
</g>
</g>
</g>
</svg>
</button>
<button class="caller__frames_acts_btn j-caller__ctrl" data-target="audio">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19" version="1.1">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-347.000000, -80.000000)">
<g transform="translate(344.000000, 78.000000)">
<path d="M0 0L24 0 24 24 0 24 0 0Z"/>
<path class="svg_icon" d="M19 11L17.3 11C17.3 11.74 17.14 12.43 16.87 13.05L18.1 14.28C18.66 13.3 19 12.19 19 11L19 11ZM14.98 11.17C14.98 11.11 15 11.06 15 11L15 5C15 3.34 13.66 2 12 2 10.34 2 9 3.34 9 5L9 5.18 14.98 11.17 14.98 11.17ZM4.27 3L3 4.27 9.01 10.28 9.01 11C9.01 12.66 10.34 14 12 14 12.22 14 12.44 13.97 12.65 13.92L14.31 15.58C13.6 15.91 12.81 16.1 12 16.1 9.24 16.1 6.7 14 6.7 11L5 11C5 14.41 7.72 17.23 11 17.72L11 21 13 21 13 17.72C13.91 17.59 14.77 17.27 15.54 16.82L19.73 21 21 19.73 4.27 3 4.27 3Z"/>
</g>
</g>
</g>
</svg>
</button>
<button class="caller__frames_acts_btn_record j-record" alt="record video">
</button>
</div>
<div class="caller__frames_fl">
<select class="qb-select j-filter">
<option value="no">No Filter</option>
<option value="_1977">1977</option>
<option value="inkwell">inkwell</option>
<option value="moon">moon</option>
<option value="nashville">nashville</option>
<option value="slumber">slumber</option>
<option value="toaster">toaster</option>
<option value="walden">walden</option>
</select>
</div>
<div class="caller__frames_source">
<select class="qb-select j-source invisible">
</select>
</div>
</div>
</div>
</script>
<script type="text/template" id="users_tpl">
<div class="users__title" title="Choose a user to call">
Choose a user to call
<button class="users__refresh j-users__refresh" title="click to refresh">
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="UI" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Main" transform="translate(-435.000000, -178.000000)">
<g id="ic_refresh" transform="translate(431.000000, 174.000000)">
<g id="Icon-24px" sketch:type="MSShapeGroup">
<path d="M0,0 L24,0 L24,24 L0,24 L0,0 Z" id="Shape"></path>
<path d="M17.65,6.35 C16.2,4.9 14.21,4 12,4 C7.58,4 4.01,7.58 4.01,12 C4.01,16.42 7.58,20 12,20 C15.73,20 18.84,17.45 19.73,14 L17.65,14 C16.83,16.33 14.61,18 12,18 C8.69,18 6,15.31 6,12 C6,8.69 8.69,6 12,6 C13.66,6 15.14,6.69 16.22,7.78 L13,11 L20,11 L20,4 L17.65,6.35 L17.65,6.35 Z" id="Shape" fill="#808080"></path>
</g>
</g>
</g>
</g>
</svg>
</button>
</div>
<div class="users__list j-users">
</div>
</script>
<script type="text/template" id="user_tpl">
<div class="users__item">
<button class="users__user j-user" data-id="<%= id %>" data-login="<%= login %>" data-name="<%= full_name %>">
<i class="user__icon"></i>
<span class="user__name"><%= full_name %></span>
<i class="users__btn_remove j-user-remove"></i>
</button>
</div>
</script>
<script type="text/template" id="callee_video">
<div class="frames_callee callees__callee j-callee">
<div class="frames_callee__inner">
<p class="frames_callee__status j-callee_status_<%=userID%>">
<%=state%>
</p>
<div class="qb-video">
<video class="j-callees__callee__video qb-video_source" id="remote_video_<%=userID%>" data-user="<%=userID%>">
</video>
</div>
</div>
<p class="frames_callee__name">
<%=name%>
</p>
</div>
</script>
<!-- SCRIPT -->
<!-- dependencies -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="cordova.js"></script>
<script>
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
console.log("onDeviceReady");
// Just for iOS devices.
// Read more here https://github.com/eface2face/cordova-plugin-iosrtc
if (window.device.platform === 'iOS') {
cordova.plugins.iosrtc.registerGlobals();
} else if (window.device.platform === 'Android') {
//
}
// Load JavaScript files async
//
var loadScriptAsync = function(path) {
var jsScript = document.createElement("script");
jsScript.type = "text/javascript";
jsScript.async = false; //async is being set to false so that script will not immediately fire.
jsScript.src = path;
document.getElementsByTagName("body")[0].appendChild(jsScript);
}
loadScriptAsync("https://cdnjs.cloudflare.com/ajax/libs/quickblox/2.4.0/quickblox.min.js");
loadScriptAsync("config.js")
loadScriptAsync("js/helpers.js")
loadScriptAsync("js/stateBoard.js")
loadScriptAsync("js/app.js")
}
// Listen for orientation changes and scroll
//
window.addEventListener('orientationchange', updatedVideoFrames);
window.addEventListener('scroll', updatedVideoFrames);
//
function updatedVideoFrames() {
if (window.device.platform === 'iOS') {
cordova.plugins.iosrtc.refreshVideos();
}
}
</script>
<!-- hack for github Pages -->
<script>
var host = "quickblox.github.io";
if ((host == window.location.host) && (window.location.protocol != "https:"))
window.location.protocol = "https";
</script>
</body>
</html>