3

Boy-oh-boy我討厭外部接口嗎?我有一個視頻播放器,利用外部接口來控制Flash對象,並允許Flash對象將消息傳遞給相同的JavaScript。一段時間以來,它在所有瀏覽器中運行良好。然後前幾天我就去在所有瀏覽器進行測試之前,我感動項目進行開發,並發現該應用程序在Internet Explorer 9打破在控制檯中出現以下錯誤:外部接口和Internet Explorer 9問題

SCRIPT16389: Could not complete the operation due to error 8070000c. 
jquery.min.js, line 16 character 29366 

我JavaScript文件真的很長,但這裏是重要的部分。我所有的行爲都包含在我創建的對象中。裏面的我的方法之一,我有以下行:

var that = this; 
that.stop(); 

這裏是所有被調用作爲方法的結果的方法:

this.stop = function(){ 
    var that = this; 
    console.log('stop called'); 
    that.pause(); 
    that.seek(0); 
    that.isPlaying = false; 
    console.log('stop finished'); 
}; 

this.pause = function(){ 
    var that = this; 
     console.log('pause called'); 
    if(that.player == 'undefined' || that.player == null){ 
     that.player = that.GetMediaObject(that.playerID); 
    } 
    that.player.pauseMedia(); //external interface call 
    that.isPlaying = false; 
    console.log('pause finished'); 
}; 

this.seek = function(seek){     
    var that = this; 
    console.log('seek called'); 
    if(that.player == 'undefined' || that.player ==null){ 
     console.log("player="+that.player+". resetting player object"); 
     that.player = that.GetMediaObject(that.playerID); 
     console.log("player="+that.player); 
    } 
    that.player.scrubMedia(seek); //external interface call 

    console.log('seek finished');    
}; 

//this method returns a reference to my player. This method is call once when the page loads and then again as necessary by all methods that make external interface calls 
this.GetMediaObject = function(playerID){ 
    var mediaObj = swfobject.getObjectById(playerID); 
     console.log('fetching media object: ' +mediaObj); 

     //if swfobject.getObjectById fails 
     if(typeof mediaObj == 'undefined' || mediaObj == null){ 
       console.log('secondary fetch required'); 
     var isIE = navigator.userAgent.match(/MSIE/i); 
     mediaObj = isIE ? window[playerID] : document[playerID]; 
    } 

    return mediaObj; 
}; 

下面是從我的console.log statments輸出:

LOG: fetching media object: [object HTMLObjectElement] 
LOG: video-obj-1: ready 
LOG: stop called 
LOG: pause called 
LOG: pause finished 
LOG: seek called 
LOG: player=[object HTMLObjectElement] 
SCRIPT16389: Could not complete the operation due to error 8070000c. 
jquery.min.js, line 16 character 29366 

有趣的是,它似乎是第一個外部接口調用「that.player.pauseMedia()」沒有任何問題,但後續調用「that.player.scrubMedi一個(0)'失敗。另一個奇怪的是,它指向jquery作爲錯誤的來源,但在這些函數中沒有對jquery的調用。

這是我所知道的不是。這不是我的時機關閉的問題。當flash對象完全加載時,我的動作的最後一行向javascript發送消息。另外我將參數'allowScriptAccess'設置爲'always',所以它不是那樣。我們使用的actionscript文件已經在以前的項目中使用過,所以我90%確定這不是問題。

這裏是我的動作無論如何。我沒有寫動作,我不是太熟悉的語言,但我試圖把似乎最爲相關的我的應用程序的部分:

flash.system.Security.allowDomain("*.mydomain.com"); 

import flash.external.ExternalInterface; 

// variables to store local information about the current media 
var mediaEmbedServer:String = "www"; 
var mediaPlayerID:String; 
var mediaFile:String; 
var mediaDuration:Number; 

// variables to be watched by actionscript and message javascript on changes 
var mediaPositions:String = "0,0"; // buffer position, scrub position 
var mediaStatus:String; 

var netStreamClient:Object = new Object(); 
netStreamClient.onMetaData = metaDataHandler; 
netStreamClient.onCuePoint = cuePointHandler; 

var connection:NetConnection; 
var stream:NetStream; 
var media:Video = new Video(); 

// grab the media's duration when it becomes available 
function metaDataHandler(info:Object):void { 
mediaDuration = info.duration; 
} 

function cuePointHandler(info:Object):void { 
} 

connection = new NetConnection(); 
connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); 
connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); 

try { 
var paramName:String; 
var paramValue:String; 
var paramObject:Object = LoaderInfo(this.root.loaderInfo).parameters; 
for (paramName in paramObject) { 
paramValue = String(paramObject[paramName]); 
switch (paramName){ 
case "server": 
mediaEmbedServer = paramValue; 
break 
case "playerID": 
mediaPlayerID = paramValue; 
break 
} 
} 
} catch (error:Error) { 
} 

if (mediaEmbedServer == "dev" || mediaEmbedServer == "dev2"){ 
connection.connect("rtmp://media.developmentMediaServer.com/myApp"); 
} else { 
connection.connect("rtmp://media.myMediaServer.com/myApp"); 
} 

function securityErrorHandler(event:SecurityErrorEvent):void { 
trace("securityErrorHandler: " + event); 
} 

function connectStream():void { 
stream = new NetStream(connection); 
stream.soundTransform = new SoundTransform(1); 
stream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); 
stream.client = netStreamClient; 
media.attachNetStream(stream); 
media.width = 720; 
media.height = 405; 
addChild(media); 
} 

function netStatusHandler(stats:NetStatusEvent){ 
switch (stats.info.code){ 
case "NetConnection.Connect.Success": 
connectStream(); 
break; 
case "NetConnection.Call.BadVersion": 
case "NetConnection.Call.Failed": 
case "NetConnection.Call.Prohibited": 
case "NetConnection.Connect.AppShutdown": 
case "NetConnection.Connect.Failed": 
case "NetConnection.Connect.InvalidApp": 
case "NetConnection.Connect.Rejected": 
case "NetGroup.Connect.Failed": 
case "NetGroup.Connect.Rejected": 
case "NetStream.Connect.Failed": 
case "NetStream.Connect.Rejected": 
case "NetStream.Failed": 
case "NetStream.Play.Failed": 
case "NetStream.Play.FileStructureInvalid": 
case "NetStream.Play.NoSupportedTrackFound": 
case "NetStream.Play.StreamNotFound": 
case "NetStream.Seek.Failed": 
case "NetStream.Seek.InvalidTime": 
// report error status and reset javascriptPlay 
clearInterval(progressInterval); 
messageStatus("error"); 
break; 
default: 
// check time through file to determine if media is over 
if (stream.time > 0 && stream.time >= (mediaDuration - .25)){ 
// reset media if it has ended 
clearInterval(progressInterval); 
stream.play(mediaFile, 0, 0); 
messageStatus("finished"); 
} 
} 
}; 

var progressInterval:Number; 

// respond to a play/pause request by playing/pausing the current stream 
function pauseMedia(){ 
clearInterval(progressInterval); 
if (mediaStatus == 'playing'){ 
stream.pause(); 
messageStatus("paused"); 
} 
}; 
ExternalInterface.addCallback("pauseMedia", pauseMedia); 

// respond to a scrub request by seeking to a position in the media 
function scrubMedia(newPosition){ 
clearInterval(progressInterval); 
if (mediaStatus == "playing"){ 
stream.pause(); 
messageStatus("paused"); 
} 
stream.seek(newPosition * mediaDuration); 
var positionSeconds = newPosition * mediaDuration; 
messagePositions(positionSeconds+","+positionSeconds); 
}; 
ExternalInterface.addCallback("scrubMedia", scrubMedia); 


ExternalInterface.call("MediaPlayerReady", mediaPlayerID); 

回答

0

聽起來像一個undefined expando property可以由jQuery IE9 bug引起。調試它的最好方法是,除去的userAgent測試和用對象元件的檢查替換它,如:

document.getElementsByTagName("object")[0].outerHTML 

看有無ID屬性由jQuery的第一次點擊之後被改變。

0

我有使用JPEGCam,也使用Flash的外部接口這個問題。我的攝像頭控制被動態加載到一個div中,然後將這個錯誤引入IE(不是Firefox或Chrome)。將閃存控件的初始化移動到父頁面中的document.ready後,根據需要隱藏/顯示/移動控件,我可以解決此異常。

希望有所幫助。