Внешний интерфейс и проблема Internet Explorer 9 - PullRequest
3 голосов
/ 14 января 2012

Мальчик-ой-мальчик, я ненавижу внешний интерфейс. У меня есть видеоплеер, который использует внешний интерфейс для управления объектом Flash и позволяет объекту Flash передавать сообщения в один и тот же JavaScript. Некоторое время это работало хорошо во всех браузерах. Затем несколько дней назад я отправился протестировать его во всех браузерах, прежде чем вывести проект из разработки, и обнаружил, что приложение не работает в 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:

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.scrubMedia (0) не выполняется. Еще одна странность в том, что она указывает на jquery как источник ошибки, но в этих функциях нет вызова jquery.

Вот что я знаю, что это не так. Это не проблема, когда у меня нет времени. Последняя строка моего Actionscript отправляет сообщение в JavaScript, когда Flash-объект полностью загружен. Также я установил параметр 'allowScriptAccess' на 'Always', так что это тоже не так. Используемый нами файл actionscript использовался в предыдущих проектах, поэтому я на 90% уверен, что это не проблема.

вот мой скрипт действий в любом случае. Я не писал ActionScript, и я не слишком знаком с языком, но я попытался описать те части, которые казались наиболее подходящими для моего приложения:

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);   

Ответы [ 2 ]

0 голосов
/ 08 октября 2013

У меня была эта проблема при использовании JPEGCam, который также использует внешний интерфейс flash.Элемент управления моей веб-камеры загружался динамически в DIV, а затем выдает эту ошибку в IE (не Firefox или Chrome).После перемещения инициализации моего элемента управления флэш-памятью на document.ready на родительской странице, а затем при необходимости скрывая / показывая / перемещая элемент управления, я смог обойти это исключение.

Надеюсь, что это поможет.

0 голосов
/ 21 августа 2012

Похоже на неопределенное свойство expando , которое может быть вызвано ошибкой jQuery IE9 .Лучший способ его отладки - удалить тест userAgent и заменить его проверкой на предметный элемент, например:

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

, чтобы увидеть, изменяется ли атрибут ID после первого щелчка по jQuery..

...