从第 3 方设备(具有 "Videophone" 功能)调用 Linphone(桌面)显示视频,而调用 Linphone(浏览器)不
Calling from 3rd party device (with "Videophone" capabilities) to Linphone(Desktop) displays video while calling Linphone(Browser) does not
我正在尝试编写一个概念证明,以表明具有 "Videophone" 功能的第 3 方硬件设备可以调用同一 LAN 上的 Web 应用程序。在设备制造商的推荐下,我正在使用linphone。
首先,Windows 的 Linphone 完美运行 (在视频编解码器下启用 H263 后) 所以澄清一下,第 3 方设备使用 H263 视频编解码器。
Linphone 用于浏览器 使用我的概念证明,当从 linphone 调用 windows 时显示视频,但从第三部分设备调用时不显示视频。
第一个问题
经过一些挖掘 https://www.linphone.org/docs/linphone-web/external-LinphoneCore.html 并查看 "core.videoCodecs" 的结果后,我注意到
返回的唯一视频编解码器是 VP8。
经过更多挖掘,x-linphone-web 插件默认不包含所有编解码器。所以我重新编译了支持 "H263" 的插件。 "core.videoCodecs"
现在返回 "H263" 作为编解码器之一。此时,当我从第 3 方设备调用我的概念证明时仍然没有视频。
我试过的其他东西:
- 操纵linphone核心参数。 (videoPort, videoPolicy, ...)
- 以不同方式接听电话。使用 acceptCall、acceptCallWithParams、acceptEarlyMedia 后接 acceptCall。
我注意到 windows 的 linphone 将其配置导出到 linphonerc 文件。 尝试使用与 windows
的 linphone 相同的参数初始化 linphone 核心
3.1 尝试使用 core.init('URI to file using the format file:///C:/test.linphonerc');这导致了无效的 URI 错误。
3.2 尝试使用 core.init('URI to file using the format 'local:///test.linphonerc');这并没有导致错误,但创建了新文件 C:\Users***\AppData\Local\Temp\linphone-webd89-653a-c164-9d79\test.linphonerc
3.3 尝试使用 newLpConfig('local:///test.linphonerc') 在代码中创建文件,然后使用 core.init('local:///test.linphonerc') 进行初始化。 newLpConfig 写入 C:\Users***\AppData\Local\Temp\linphone-web\ 中的一个新文件夹,init 尝试从 C:\Users***\AppData\Local\Temp\linphone-web\
[ 中的另一个新文件夹中读取=85=]
查看 wireshark 日志 以了解为 windows 调用 linphone 与从第 3 方设备使用 linphone 浏览器调用概念验证之间的区别。
4.1 Linphone(Windows) 以“101 对话建立”回复 SIP 邀请,而 Linphone(Browser) 以“100 尝试”回复 SIP 邀请
4.2 当按下 "answer call" 按钮时,Linphone(Windows) 回复“200 OK”,其中包括 SDP 媒体描述 "Media Description, name and address (m): video 9078 RTP/AVP 34" 而 Linphone(浏览器)回复 "200 OK" 并带有媒体描述 "Media Description, name and address (m): video 0 RTP/AVP 0"
4.3 在回答时,Linphone(Windows) 回复 “200 OK”,其中包含 SDP 媒体属性 "Media Attribute (a): rtpmap:34 H263/90000" 而 Linphone(浏览器)回复 “200 OK” 没有视频媒体属性。
以防有人想看代码。
linphone.html
<html>
<head>
<script type="text/javascript" src="linphone.js"></script>
</head>
<body onload="initLinphoneCore()" style="background:#000000; font-family : Arial; font-size: 12;">
<object id="core" type="application/x-linphone-web" width="0" height="0">
<param name="onload" value='initLinphoneCore()'>
</object>
<div style="width : 640px; height : 480px; position : absolute; top : 30%; left : 30%; right : 30%; background : #EEEEEE;">
<div id="status" style="position:relative; height:30px; font-size:18px;top:0px; background:#888888; color:#FFFFFF;text-align: center;"></div>
<div id="videoContainer1" style="position:relative; top: 25%; left:25%;" ></div>
<div style="position:absolute; width : 100%; height:30px; font-size:18px; bottom:0px; text-align: right; background : #333333;">
<input type="button" OnClick="answerCall()" value="Answer Call">
</div>
</div>
</body>
</html>
linphone.js
var CallStatusIdle = 0;
var CallStatusIncomingReceived = 1;
var CallStatusConnected = 6;
var CallStatusStreamsRunning = 7;
var CallStatusError = 12;
var CallStatusEnd = 13;
var currentCall;
var currentCallStatus = CallStatusIdle;
//-------------------------------------------------------------------------------------------------------
// Name : addEvent
// Desc : Register to be notified of an event.
// param obj :
// param name :
// param func :
//-------------------------------------------------------------------------------------------------------
function addEvent(obj, name, func)
{
if (obj.attachEvent) {
obj.attachEvent("on"+name, func);
} else {
obj.addEventListener(name, func, false);
}
}
//-------------------------------------------------------------------------------------------------------
// Name : updateStatus
// Desc : Function that display some text in a html element.
// param id :
// param value :
// param bgColour:
// param fgColour:
//-------------------------------------------------------------------------------------------------------
function updateStatus(id, value, bgColour, fgColour)
{
document.getElementById(id).innerHTML= value;
document.getElementById(id).style.background = bgColour;
document.getElementById(id).style.color = fgColour;
}
//-------------------------------------------------------------------------------------------------------
// Name : getCore
// Desc : Get a reference to linphone core.
//-------------------------------------------------------------------------------------------------------
function getCore()
{
return document.getElementById('core');
}
//-------------------------------------------------------------------------------------------------------
// Title : initLinphoneCore.
// Desc : Initialise the linphone core.
//-------------------------------------------------------------------------------------------------------
function initLinphoneCore()
{
var core = getCore();
addEvent(core, "callStateChanged", onCallStateChanged);
/*
Initial attempt was to initialise using core.init();
Haven't managed to get that working so attempt "n" is to specify the configuration as exported using
the windows desktop version of linphone.
*/
var config = core.newLpConfig("local:///config.linphonerc");
config.cleanSection("rtp");
config.setString('rtp', 'download_ptime', "0");
config.setString('rtp', 'audio_rtp_port', "7078");
config.setString('rtp', 'video_rtp_port', "9078");
config.setString('rtp', 'audio_jitt_comp', "60");
config.setString('rtp', 'video_jitt_comp', "60");
config.setString('rtp', 'nortp_timeout', "30");
config.setString('rtp', 'audio_adaptive_jitt_comp_enabled', "1");
config.setString('rtp', 'video_adaptive_jitt_comp_enabled', "1");
config.setString('rtp', 'audio_dscp', "0x2e");
config.setString('rtp', 'video_dscp', "0x2e");
config.cleanSection("sip");
config.setString('sip', 'media_encryption', "none");
config.setString('sip', 'default_proxy', "-1");
config.setString('sip', 'sip_port', "5062");
config.setString('sip', 'sip_tcp_port', "0");
config.setString('sip', 'sip_tls_port', "0");
config.setString('sip', 'use_info', "1");
config.setString('sip', 'guess_hostname', "1");
config.setString('sip', 'inc_timeout', "30");
config.setString('sip', 'in_call_timeout', "0");
config.setString('sip', 'delayed_timeout', "4");
config.setString('sip', 'use_ipv6', "0");
config.setString('sip', 'register_only_when_network_is_up', "1");
config.setString('sip', 'register_only_when_upnp_is_ok', "1");
config.setString('sip', 'dscp', "0x1a");
config.cleanSection("video");
config.setString('video', 'display', "1");
config.setString('video', 'capture', "1");
config.setString('video', 'automatically_initiate', "1");
config.setString('video', 'automatically_accept', "1");
config.setString('video', 'show_local', "0");
config.setString('video', 'self_view', "0");
config.setString('video', 'size', "svga");
// config.setString('video', 'device', "Removed for SO Question");
config.cleanSection("net");
config.setString('net', 'download_bw', "0");
config.setString('net', 'upload_bw', "0");
config.setString('net', 'adaptive_rate_control', "1");
config.setString('net', 'firewall_policy', "0");
config.setString('net', 'mtu', "1300");
config.cleanSection("sound");
// config.setString('sound', 'playback_dev_id', "Removed for SO Question");
// config.setString('sound', 'ringer_dev_id', "Removed for SO Question");
// config.setString('sound', 'capture_dev_id', "Removed for SO Question");
config.setString('sound', 'echocancellation', "0");
config.setString('sound', 'mic_gain_db', "0.000000");
config.setString('sound', 'local_ring', "C:\Program Files (x86)\Linphone\share\sounds\linphone\rings\oldphone.wav");
config.setString('sound', 'playback_gain_db', "0.000000");
config.cleanSection("video_codec_0");
config.setString('video_codec_0', 'mime', "H263");
config.setString('video_codec_0', 'rate', "90000");
config.setString('video_codec_0', 'enabled', "1");
config.setString('video_codec_0', 'recv_fmtp', "");
config.cleanSection("video_codec_1");
config.setString('video_codec_1', 'mime', "VP8");
config.setString('video_codec_1', 'rate', "90000");
config.setString('video_codec_1', 'enabled', "1");
config.cleanSection("video_codec_2");
config.setString('video_codec_2', 'mime', "H263-1998");
config.setString('video_codec_2', 'rate', "90000");
config.setString('video_codec_2', 'enabled', "1");
config.setString('video_codec_2', 'recv_fmtp', "1;QCIF=1");
// Write configuration file:
var configFileSynch = config.sync();
if ( configFileSynch !== 0 ) {
console.log( 'Failed to write configuration file.' );
return;
}
// Initialise core:
var coreInit = core.init( 'local:///config.linphonerc' );
if ( coreInit !== 0 )
{
console.log( 'Failed to initialise core.' );
return;
}
// Setup core logging.
core.logHandler = function( level, message )
{
window.console.log(message);
}
// Start main loop:
core.iterateEnabled = true;
updateStatus ( 'status', 'Linphone Core Initialised', "#888888", '#FFFFFF');
}
//-------------------------------------------------------------------------------------------------------
// Name : onCallStateChanged
// Desc : On notification of call status, decide on the logic to perform.
// param event : The event that triggered all of this.
// param call : The call object that had its state changed.
// param state : The new state of the call.
// param message : A description of the call state.
//-------------------------------------------------------------------------------------------------------
function onCallStateChanged(event, call, state, message)
{
try {
// Keep a reference for later use:
currentCall = call;
currentCallStatus = state;
// Log new call state:
window.console.log('Call state changed : ' + state);
if ( CallStatusIncomingReceived === state )
{
updateStatus('status', message, "#0000AA", '#FFFFFF');
document.getElementById('videoContainer1').innerHTML= "<object id='remoteVideo1' type='application/x-linphone-web-video' style='display: inline; width: 320px; height: 240px; position:absolute'><param name='onload' value='onLoadVideo1' /><param name='magic' value='1' /></object>";
}
else if ( CallStatusConnected === state )
{
updateStatus('status', message, "#000000", '#FFFFFF');
}
else if( CallStatusStreamsRunning === state )
{
updateStatus('status', message, "#00AA00", '#FFFFFF');
}
else if( CallStatusEnd === state )
{
updateStatus('status', message, "#000000", '#FFFFFF');
}
else if( CallStatusError === state )
{
updateStatus('status', message, "#440000", '#FFFFFF');
}
}
catch (err)
{
var msg = "There was an error during call status change : " + err.message;
console.log ( msg );
updateStatus ( 'status', msg, "#000000", '#FFFFFF');
}
}
//-------------------------------------------------------------------------------------------------------
// Name : answerCall
// Desc : User clicked button to answer call.
//-------------------------------------------------------------------------------------------------------
function answerCall()
{
try {
core.acceptCall ( currentCall) ;
}
catch (err)
{
var msg = "There was an error while answering call : " + err.message;
console.log ( msg );
updateStatus ( 'status', msg, "#000000", '#FFFFFF');
}
}
//-------------------------------------------------------------------------------------------------------
// Name : onLoadVideo1
// Desc : Initialise video parameters after x-linphone-web-video injected and loaded.
//-------------------------------------------------------------------------------------------------------
function onLoadVideo1() {
var v = document.getElementById('remoteVideo1');
core.videoPolicy.automaticallyAccept = true;
core.videoDisplayEnabled = true;
core.nativeVideoWindowId = v.window;
}
知道为什么在为 windows 调用 Linphone 时显示视频,但在调用我的使用 Linphone 浏览器的概念证明时却不显示视频吗?
这是我关于 https://whosebug.com/ 的第一个问题。如果您有任何改进此问题的建议,请告诉我。
今天早上我在 linphone 开发人员邮件列表中发布了同样的问题。我收到了回复,实施后解决了我的问题。
Link 到邮件列表并回复。 http://lists.gnu.org/archive/html/linphone-developers/2015-05/msg00086.html
基本上,既然插件支持 H263,我必须启用编解码器。
在我的概念验证中启用 H263 编解码器。
core.enablePayloadType ( core.videoCodecs[2], true );
我正在尝试编写一个概念证明,以表明具有 "Videophone" 功能的第 3 方硬件设备可以调用同一 LAN 上的 Web 应用程序。在设备制造商的推荐下,我正在使用linphone。
首先,Windows 的 Linphone 完美运行 (在视频编解码器下启用 H263 后) 所以澄清一下,第 3 方设备使用 H263 视频编解码器。
Linphone 用于浏览器 使用我的概念证明,当从 linphone 调用 windows 时显示视频,但从第三部分设备调用时不显示视频。
第一个问题
经过一些挖掘 https://www.linphone.org/docs/linphone-web/external-LinphoneCore.html 并查看 "core.videoCodecs" 的结果后,我注意到 返回的唯一视频编解码器是 VP8。
经过更多挖掘,x-linphone-web 插件默认不包含所有编解码器。所以我重新编译了支持 "H263" 的插件。 "core.videoCodecs" 现在返回 "H263" 作为编解码器之一。此时,当我从第 3 方设备调用我的概念证明时仍然没有视频。
我试过的其他东西:
- 操纵linphone核心参数。 (videoPort, videoPolicy, ...)
- 以不同方式接听电话。使用 acceptCall、acceptCallWithParams、acceptEarlyMedia 后接 acceptCall。
我注意到 windows 的 linphone 将其配置导出到 linphonerc 文件。 尝试使用与 windows
的 linphone 相同的参数初始化 linphone 核心3.1 尝试使用 core.init('URI to file using the format file:///C:/test.linphonerc');这导致了无效的 URI 错误。
3.2 尝试使用 core.init('URI to file using the format 'local:///test.linphonerc');这并没有导致错误,但创建了新文件 C:\Users***\AppData\Local\Temp\linphone-webd89-653a-c164-9d79\test.linphonerc
3.3 尝试使用 newLpConfig('local:///test.linphonerc') 在代码中创建文件,然后使用 core.init('local:///test.linphonerc') 进行初始化。 newLpConfig 写入 C:\Users***\AppData\Local\Temp\linphone-web\ 中的一个新文件夹,init 尝试从 C:\Users***\AppData\Local\Temp\linphone-web\
[ 中的另一个新文件夹中读取=85=]查看 wireshark 日志 以了解为 windows 调用 linphone 与从第 3 方设备使用 linphone 浏览器调用概念验证之间的区别。
4.1 Linphone(Windows) 以“101 对话建立”回复 SIP 邀请,而 Linphone(Browser) 以“100 尝试”回复 SIP 邀请
4.2 当按下 "answer call" 按钮时,Linphone(Windows) 回复“200 OK”,其中包括 SDP 媒体描述 "Media Description, name and address (m): video 9078 RTP/AVP 34" 而 Linphone(浏览器)回复 "200 OK" 并带有媒体描述 "Media Description, name and address (m): video 0 RTP/AVP 0"
4.3 在回答时,Linphone(Windows) 回复 “200 OK”,其中包含 SDP 媒体属性 "Media Attribute (a): rtpmap:34 H263/90000" 而 Linphone(浏览器)回复 “200 OK” 没有视频媒体属性。
以防有人想看代码。
linphone.html
<html>
<head>
<script type="text/javascript" src="linphone.js"></script>
</head>
<body onload="initLinphoneCore()" style="background:#000000; font-family : Arial; font-size: 12;">
<object id="core" type="application/x-linphone-web" width="0" height="0">
<param name="onload" value='initLinphoneCore()'>
</object>
<div style="width : 640px; height : 480px; position : absolute; top : 30%; left : 30%; right : 30%; background : #EEEEEE;">
<div id="status" style="position:relative; height:30px; font-size:18px;top:0px; background:#888888; color:#FFFFFF;text-align: center;"></div>
<div id="videoContainer1" style="position:relative; top: 25%; left:25%;" ></div>
<div style="position:absolute; width : 100%; height:30px; font-size:18px; bottom:0px; text-align: right; background : #333333;">
<input type="button" OnClick="answerCall()" value="Answer Call">
</div>
</div>
</body>
</html>
linphone.js
var CallStatusIdle = 0;
var CallStatusIncomingReceived = 1;
var CallStatusConnected = 6;
var CallStatusStreamsRunning = 7;
var CallStatusError = 12;
var CallStatusEnd = 13;
var currentCall;
var currentCallStatus = CallStatusIdle;
//-------------------------------------------------------------------------------------------------------
// Name : addEvent
// Desc : Register to be notified of an event.
// param obj :
// param name :
// param func :
//-------------------------------------------------------------------------------------------------------
function addEvent(obj, name, func)
{
if (obj.attachEvent) {
obj.attachEvent("on"+name, func);
} else {
obj.addEventListener(name, func, false);
}
}
//-------------------------------------------------------------------------------------------------------
// Name : updateStatus
// Desc : Function that display some text in a html element.
// param id :
// param value :
// param bgColour:
// param fgColour:
//-------------------------------------------------------------------------------------------------------
function updateStatus(id, value, bgColour, fgColour)
{
document.getElementById(id).innerHTML= value;
document.getElementById(id).style.background = bgColour;
document.getElementById(id).style.color = fgColour;
}
//-------------------------------------------------------------------------------------------------------
// Name : getCore
// Desc : Get a reference to linphone core.
//-------------------------------------------------------------------------------------------------------
function getCore()
{
return document.getElementById('core');
}
//-------------------------------------------------------------------------------------------------------
// Title : initLinphoneCore.
// Desc : Initialise the linphone core.
//-------------------------------------------------------------------------------------------------------
function initLinphoneCore()
{
var core = getCore();
addEvent(core, "callStateChanged", onCallStateChanged);
/*
Initial attempt was to initialise using core.init();
Haven't managed to get that working so attempt "n" is to specify the configuration as exported using
the windows desktop version of linphone.
*/
var config = core.newLpConfig("local:///config.linphonerc");
config.cleanSection("rtp");
config.setString('rtp', 'download_ptime', "0");
config.setString('rtp', 'audio_rtp_port', "7078");
config.setString('rtp', 'video_rtp_port', "9078");
config.setString('rtp', 'audio_jitt_comp', "60");
config.setString('rtp', 'video_jitt_comp', "60");
config.setString('rtp', 'nortp_timeout', "30");
config.setString('rtp', 'audio_adaptive_jitt_comp_enabled', "1");
config.setString('rtp', 'video_adaptive_jitt_comp_enabled', "1");
config.setString('rtp', 'audio_dscp', "0x2e");
config.setString('rtp', 'video_dscp', "0x2e");
config.cleanSection("sip");
config.setString('sip', 'media_encryption', "none");
config.setString('sip', 'default_proxy', "-1");
config.setString('sip', 'sip_port', "5062");
config.setString('sip', 'sip_tcp_port', "0");
config.setString('sip', 'sip_tls_port', "0");
config.setString('sip', 'use_info', "1");
config.setString('sip', 'guess_hostname', "1");
config.setString('sip', 'inc_timeout', "30");
config.setString('sip', 'in_call_timeout', "0");
config.setString('sip', 'delayed_timeout', "4");
config.setString('sip', 'use_ipv6', "0");
config.setString('sip', 'register_only_when_network_is_up', "1");
config.setString('sip', 'register_only_when_upnp_is_ok', "1");
config.setString('sip', 'dscp', "0x1a");
config.cleanSection("video");
config.setString('video', 'display', "1");
config.setString('video', 'capture', "1");
config.setString('video', 'automatically_initiate', "1");
config.setString('video', 'automatically_accept', "1");
config.setString('video', 'show_local', "0");
config.setString('video', 'self_view', "0");
config.setString('video', 'size', "svga");
// config.setString('video', 'device', "Removed for SO Question");
config.cleanSection("net");
config.setString('net', 'download_bw', "0");
config.setString('net', 'upload_bw', "0");
config.setString('net', 'adaptive_rate_control', "1");
config.setString('net', 'firewall_policy', "0");
config.setString('net', 'mtu', "1300");
config.cleanSection("sound");
// config.setString('sound', 'playback_dev_id', "Removed for SO Question");
// config.setString('sound', 'ringer_dev_id', "Removed for SO Question");
// config.setString('sound', 'capture_dev_id', "Removed for SO Question");
config.setString('sound', 'echocancellation', "0");
config.setString('sound', 'mic_gain_db', "0.000000");
config.setString('sound', 'local_ring', "C:\Program Files (x86)\Linphone\share\sounds\linphone\rings\oldphone.wav");
config.setString('sound', 'playback_gain_db', "0.000000");
config.cleanSection("video_codec_0");
config.setString('video_codec_0', 'mime', "H263");
config.setString('video_codec_0', 'rate', "90000");
config.setString('video_codec_0', 'enabled', "1");
config.setString('video_codec_0', 'recv_fmtp', "");
config.cleanSection("video_codec_1");
config.setString('video_codec_1', 'mime', "VP8");
config.setString('video_codec_1', 'rate', "90000");
config.setString('video_codec_1', 'enabled', "1");
config.cleanSection("video_codec_2");
config.setString('video_codec_2', 'mime', "H263-1998");
config.setString('video_codec_2', 'rate', "90000");
config.setString('video_codec_2', 'enabled', "1");
config.setString('video_codec_2', 'recv_fmtp', "1;QCIF=1");
// Write configuration file:
var configFileSynch = config.sync();
if ( configFileSynch !== 0 ) {
console.log( 'Failed to write configuration file.' );
return;
}
// Initialise core:
var coreInit = core.init( 'local:///config.linphonerc' );
if ( coreInit !== 0 )
{
console.log( 'Failed to initialise core.' );
return;
}
// Setup core logging.
core.logHandler = function( level, message )
{
window.console.log(message);
}
// Start main loop:
core.iterateEnabled = true;
updateStatus ( 'status', 'Linphone Core Initialised', "#888888", '#FFFFFF');
}
//-------------------------------------------------------------------------------------------------------
// Name : onCallStateChanged
// Desc : On notification of call status, decide on the logic to perform.
// param event : The event that triggered all of this.
// param call : The call object that had its state changed.
// param state : The new state of the call.
// param message : A description of the call state.
//-------------------------------------------------------------------------------------------------------
function onCallStateChanged(event, call, state, message)
{
try {
// Keep a reference for later use:
currentCall = call;
currentCallStatus = state;
// Log new call state:
window.console.log('Call state changed : ' + state);
if ( CallStatusIncomingReceived === state )
{
updateStatus('status', message, "#0000AA", '#FFFFFF');
document.getElementById('videoContainer1').innerHTML= "<object id='remoteVideo1' type='application/x-linphone-web-video' style='display: inline; width: 320px; height: 240px; position:absolute'><param name='onload' value='onLoadVideo1' /><param name='magic' value='1' /></object>";
}
else if ( CallStatusConnected === state )
{
updateStatus('status', message, "#000000", '#FFFFFF');
}
else if( CallStatusStreamsRunning === state )
{
updateStatus('status', message, "#00AA00", '#FFFFFF');
}
else if( CallStatusEnd === state )
{
updateStatus('status', message, "#000000", '#FFFFFF');
}
else if( CallStatusError === state )
{
updateStatus('status', message, "#440000", '#FFFFFF');
}
}
catch (err)
{
var msg = "There was an error during call status change : " + err.message;
console.log ( msg );
updateStatus ( 'status', msg, "#000000", '#FFFFFF');
}
}
//-------------------------------------------------------------------------------------------------------
// Name : answerCall
// Desc : User clicked button to answer call.
//-------------------------------------------------------------------------------------------------------
function answerCall()
{
try {
core.acceptCall ( currentCall) ;
}
catch (err)
{
var msg = "There was an error while answering call : " + err.message;
console.log ( msg );
updateStatus ( 'status', msg, "#000000", '#FFFFFF');
}
}
//-------------------------------------------------------------------------------------------------------
// Name : onLoadVideo1
// Desc : Initialise video parameters after x-linphone-web-video injected and loaded.
//-------------------------------------------------------------------------------------------------------
function onLoadVideo1() {
var v = document.getElementById('remoteVideo1');
core.videoPolicy.automaticallyAccept = true;
core.videoDisplayEnabled = true;
core.nativeVideoWindowId = v.window;
}
知道为什么在为 windows 调用 Linphone 时显示视频,但在调用我的使用 Linphone 浏览器的概念证明时却不显示视频吗?
这是我关于 https://whosebug.com/ 的第一个问题。如果您有任何改进此问题的建议,请告诉我。
今天早上我在 linphone 开发人员邮件列表中发布了同样的问题。我收到了回复,实施后解决了我的问题。
Link 到邮件列表并回复。 http://lists.gnu.org/archive/html/linphone-developers/2015-05/msg00086.html
基本上,既然插件支持 H263,我必须启用编解码器。
在我的概念验证中启用 H263 编解码器。
core.enablePayloadType ( core.videoCodecs[2], true );