这是一个复杂的问题,因为有很多活动部件。我提前道歉。
我正在尝试编写一个托管 Flash 相机和麦克风的 Silverlight 控件(因为 Silverlight 本身不支持这些东西,运气不好)。我编写了一个简短的 Flex 应用程序(“WLocalWebCam.swf”)来处理相机,并公开两个外部方法:connect(uri:String, streamName:String) 和 disconnect()。我可以通过 JavaScript 成功调用这些(简化为删除错误处理等):
function connectWebCam(webCamID, rtmpUri, streamName) {
var flashCam = getWebCam(webCamID);
flashCam.Connect(rtmpUri, streamName);
}
function disconnectWebCam(webCamID) {
var flashCam = getWebCam(webCamID);
flashCam.Disconnect();
}
function getWebCam(id) {
return document.getElementById(id);
}
当我从另一个 JavaScript 源(例如,按钮单击处理程序)调用这些函数时,网络摄像头正确连接到 RTMP 服务器(我使用的是 Wowza)。但是,当我在 Silverlight 的同一页面上调用完全相同的函数时,Flash 摄像头无法连接到 RTMP 服务器。
/// <summary>
/// Connect() invokes the connectWebCam() JavaScript function contained in the WebCam.js file on the website.
/// The connectWebCam() method in turn calls the Connect() method on the contained Flash web cam object.
/// </summary>
public void Connect()
{
ScriptObject connectWebCam = (ScriptObject)HtmlPage.Window.GetProperty("connectWebCam");
connectWebCam.InvokeSelf(CameraID, RtmpUri.ToString(), CameraID);
}
然而,它以一种有趣的方式失败了。ActionScript 的 connect() 方法被调用,它成功地调用了 getConnection(),但是 handleNetStatus 事件处理程序方法永远不会被调用,并且 Wowza 服务器永远不会看到连接尝试。
这是我正在使用的 ActionScript 代码,这次保留了调试位。
public function connect(uri:String, name:String):void
{
rtmpUri = uri;
streamName = name;
logMessage("Beginning attempt to open connection; rtmpUri=" + rtmpUri + "; streamName = " + streamName);
logMessage("Retrieving camera.");
cam = Camera.getCamera();
if( cam != null )
{
logMessage("Retrieved camera.");
cam.setMode( 320, 240, 20 );
cam.setQuality( 0,0 );
}
else
{
logMessage("Unable to retrieve camera instance.");
}
logMessage("Retrieving microphone.");
mic = new Microphone();
if (mic == null)
{
logMessage("Unable to retrieve microphone instance.");
}
logMessage("Retrieving NetConnection.");
chatNC = getConnection();
}
private function getConnection(): NetConnection
{
var nc: NetConnection = new NetConnection();
if (nc != null)
{
logMessage("Retrieved NetConnection().");
nc.client = this;
nc.objectEncoding = ObjectEncoding.AMF0;
nc.addEventListener( NetStatusEvent.NET_STATUS, this.handleNetStatus );
logMessage("Connecting to " + rtmpUri);
nc.connect(rtmpUri); // <-- We get successfully to this point.
}
else
{
logMessage("Unable to retrieve new NetConnection()");
}
return nc;
}
private function handleNetStatus( event:NetStatusEvent ):void
{
logMessage("[SYSTEM MESSAGE] net status " + event.info.code + " type " + event.type); // <-- We never get this far. This bit never gets called.
switch( event.info.code )
{
case "NetConnection.Connect.Success":
publishVideoStream();
break;
default:
Alert.show("Error connecting: " + event.info.code, "Error Connecting");
break;
}
}
这让我非常摸不着头脑。
有谁知道为什么如果从 Silverlight 调用与从 JavaScript 调用完全相同的 ActionScript 会表现不同?有关故障排除的任何建议吗?