Javascript Chromecast定制CAF接收器

Javascript Chromecast定制CAF接收器,javascript,chromecast,google-cast,google-cast-sdk,caf-receiver-sdk,Javascript,Chromecast,Google Cast,Google Cast Sdk,Caf Receiver Sdk,新的CAF接收器没有将YouTube iframe播放器注册为播放器,并且正在播放,我对此有意见。连接到接收器5分钟后,连接中断,因为它认为播放机空闲 这是发件人代码 var metadata = new chrome.cast.media.GenericMediaMetadata(); metadata.title = "Foo - Bar"; metadata.image = 'https://img.youtube.com/vi/IXNrHusLXoM/mqdefault.jpg'; me

新的CAF接收器没有将YouTube iframe播放器注册为播放器,并且正在播放,我对此有意见。连接到接收器5分钟后,连接中断,因为它认为播放机空闲

这是发件人代码

var metadata = new chrome.cast.media.GenericMediaMetadata();
metadata.title = "Foo - Bar";
metadata.image = 'https://img.youtube.com/vi/IXNrHusLXoM/mqdefault.jpg';
metadata.images = ['https://img.youtube.com/vi/IXNrHusLXoM/mqdefault.jpg'];
var mediaInfo = new chrome.cast.media.MediaInfo();
mediaInfo.contentType = "video/*";
mediaInfo.contentId ="IXNrHusLXoM";
mediaInfo.duration = 300;
var request = new chrome.cast.media.LoadRequest();
request.media = mediaInfo;
request.customData = customData;
request.metadata = metadata;
castSession.loadMedia(request).then(
  function() {
      console.log('Load succeed');
  },
  function(errorCode) {
      console.log('Error code: ' + errorCode);
});
可在此处找到接收器代码:

有没有办法将新的CAF接收器挂接到YouTube iframe播放器中,或者“手动”加载、缓冲、播放、暂停、停止事件,以便接收器不会与发送方断开连接


编辑:使用上述代码,PlayerState进入缓冲阶段,但在那里停止。日志“加载成功”的承诺从未触发。

YouTube iframe播放器不是为演员接收器设计的。

我设法用假MediaElement欺骗接收器。你可以看到代码

const context=cast.framework.castrecivercontext.getInstance();
const playermanger=context.getplayermanger();
var yt_events={};
var pause_request=false;
var yt_球员;
var yt_视频_假={
removeAttribute:函数(属性){
},
setAttribute:函数(属性,值){
},
getCurrentTimeSec:function(){return yt_player&&yt_player.getCurrentTime?yt_player.getCurrentTime():0;},
getDurationSec:function(){return yt_player?yt_player.getDuration():0;},
getVolume:function(){
如果(!yt_player | |!yt_player.getVolume){
返回0;
}
var volume=new cast.framework.messages.volume();
volume.level=yt_player.getVolume()/100;
volume.mute=yt_player.ismute()?真:假;
返回量;
},
setVolume:function(vol){yt_player&&yt_player.setVolume(vol.level*100);},
getState:function(){
如果(!yt_player | |!yt_player.getPlayerState){
返回“空闲”;
}
var state=yt_player.getPlayerState();
var_状态;
如果(暂停请求){
暂停请求=false;
state=YT.PlayerState.PAUSED;
}
开关(状态){
默认值:case YT.PlayerState.UNSTARTED:
_状态='空闲';
打破
案例YT.PlayerState.PLAYING:
_状态=‘玩’;
打破
案例YT.PlayerState.PAUSED:
_状态='暂停';
打破
案例YT.PlayerState.BUFFERING:
_状态='缓冲';
打破
案例YT.PlayerState.ENDED:
_状态='结束';
打破
}
返回状态;
},
addEventListener:函数(e,func){},
加载:函数(){},
play:function(){yt_player&&yt_player.playVideo();},
pause:function(){if(yt_player&&yt_player.pauseVideo){pause_request=true;yt_player.pauseVideo();},
seek:function(timeTo){yt_player&&yt_player.seekTo(timeTo,true);},
重置:函数(){
如果(yt_玩家){
尝试{yt_player.destroy&&yt_player.destroy();}捕获(e){
//控制台。跟踪(e);
};
删除yt_播放器;
}
},
registerErrorCallback:函数(func){yt_事件['error']=func;},
registerendecallback:function(func){yt_events['end']=func;},
registerLoadCallback:function(func){yt_事件['load']=func;},
unregisterErrorCallback:function(){delete yt_events['error']},
UnregisterendCallback:function(){delete yt_events['ended']},
unregisterLoadCallback:function(){delete yt_events['load']}
};
Object.defineProperty(yt_video_fake,'currentTime'{
val1:null,
get:function(){return yt_player&&yt_player.getCurrentTime?yt_player.getCurrentTime():this.val1;},
set:函数(newValue){
yt_player&&yt_player.seekTo(newValue,true);
this.val1=新值;
},
可枚举:正确,
可配置:true
});
Object.defineProperty(yt_video_fake,“volume”{
val1:null,
get:function(){var vol=this.getVolume();if(vol)返回vol['level'];返回1;},
set:函数(newValue){
yt_player&&yt_player.setVolume&&yt_player.setVolume(新值*100);
this.val1=新值;
},
可枚举:正确,
可配置:true
});
Object.defineProperty(yt_video_fake,'duration'{
val1:null,
get:function(){返回this.getDurationSec();},
set:function(){},
可枚举:正确,
可配置:true
});
功能YoutubePlayMedia(视频ID){
var yt_container=$('yt_container');
如果(!yt_容器长度){
yt_容器=$('');
$('body').append(yt_容器);
}
yt_container.html(“”);
yt\u player=新的yt.player('youtube\u容器'{
活动:{
“onReady”:函数(e){
yt_player.is_loaded=true;
yt_player.playVideo();
},
“onStateChange”:函数(e){
开关(如数据){
案例YT.PlayerState.PLAYING:
if(yt_播放器是否加载){
如果(yt_事件['load']){
yt_事件[“加载”]();
}
}
打破
案例YT.PlayerState.ENDED:
//年初至今事件['ended']和年初至今事件['ended'](e);
打破
}
},
“onError”:函数(e){
//年初至今事件['error']和年初至今事件['error'](e);
}
}
});
}
功能YoutubeLoadMedia(url){
当前_媒体_类型='Youtube';
window.onYouTubeIframeAPIReady=函数(){
window.youtube_loaded=true;
YoutubePlayMedia(url);
}
如果(!window.youtube_脚本){
window.youtube_script=document.createElement(“脚本”);
window.youtube_script.src=”https://www.youtube.com/if
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

var yt_events = {};
var pause_request = false;
var yt_player;

var yt_video_fake = {
    removeAttribute: function(attr) {
    },
    setAttribute: function(attr, val) {
    },

    getCurrentTimeSec: function() { return yt_player && yt_player.getCurrentTime ? yt_player.getCurrentTime() : 0; },
    getDurationSec: function() { return yt_player ? yt_player.getDuration() : 0; },
    getVolume: function() {
        if(!yt_player || !yt_player.getVolume) {
            return 0;
        }

        var volume = new cast.framework.messages.Volume();

        volume.level = yt_player.getVolume() / 100;
        volume.muted = yt_player.isMuted() ? true : false;

        return volume;
    },
    setVolume: function(vol) { yt_player && yt_player.setVolume(vol.level * 100); },
    getState: function() {
        if(!yt_player || !yt_player.getPlayerState) {
            return 'IDLE';
        }

        var state = yt_player.getPlayerState();
        var _state;

        if(pause_request) {
            pause_request = false;
            state = YT.PlayerState.PAUSED;
        }

        switch(state) {
            default: case YT.PlayerState.UNSTARTED:
                _state = 'IDLE';
            break;

            case YT.PlayerState.PLAYING:
                _state = 'PLAYING';
            break;

            case YT.PlayerState.PAUSED:
                _state = 'PAUSED';
            break;

            case YT.PlayerState.BUFFERING:
                _state = 'BUFFERING';
            break;

            case YT.PlayerState.ENDED:
                _state = 'ENDED';
            break;
        }

        return _state;
    },

    addEventListener: function(e, func) { },
    load: function() {},
    play: function() { yt_player && yt_player.playVideo(); },
    pause: function() { if(yt_player && yt_player.pauseVideo) {pause_request = true; yt_player.pauseVideo(); }},
    seek: function(timeTo) { yt_player && yt_player.seekTo(timeTo, true);},
    reset: function() {
        if(yt_player) {
            try { yt_player.destroy && yt_player.destroy(); } catch(e) {
                //console.trace(e);
            };
            delete yt_player;
        }
    },

    registerErrorCallback: function(func) { yt_events['error'] = func; },
    registerEndedCallback: function(func) { yt_events['ended'] = func; },
    registerLoadCallback: function(func) { yt_events['load'] = func; },

    unregisterErrorCallback: function () { delete yt_events['error'] },
    unregisterEndedCallback: function () { delete yt_events['ended']},
    unregisterLoadCallback: function () { delete yt_events['load']}
};

Object.defineProperty(yt_video_fake, 'currentTime', {
    val1: null,
    get: function() { return yt_player && yt_player.getCurrentTime ? yt_player.getCurrentTime() : this.val1; },
    set: function(newValue) {
        yt_player && yt_player.seekTo(newValue, true);
        this.val1 = newValue;
    },
    enumerable      : true,
    configurable    : true
});

Object.defineProperty(yt_video_fake, 'volume', {
    val1: null,
    get: function() { var vol = this.getVolume(); if(vol) return vol['level']; return 1; },
    set: function(newValue) {
        yt_player && yt_player.setVolume && yt_player.setVolume(newValue * 100);
        this.val1 = newValue;
    },
    enumerable      : true,
    configurable    : true
});


Object.defineProperty(yt_video_fake, 'duration', {
    val1: null,
    get: function() { return this.getDurationSec(); },
    set: function() {},
    enumerable      : true,
    configurable    : true
});


function YoutubePlayMedia(videoid) {
    var yt_container = $('#yt_container');

    if(!yt_container.length) {
        yt_container = $('<div id="yt_container" style="position:absolute;top:0;left:0;width:100%;height:100%;"></div>');
        $('body').append(yt_container);
    }

    yt_container.html('<iframe id="youtube_container" style="width:100%;height:100%;" frameborder="0" allowfullscreen="1" allow="autoplay; encrypted-media" title="YouTube video player" src="//www.youtube.com/embed/' + videoid +'?autoplay=1&enablejsapi=1&modestbranding=1&controls=0&fs=0&iv_load_policy=3&rel=0&cc_load_policy=1&cc_lang_pref=bg"></iframe>');

    yt_player = new YT.Player('youtube_container', {
        events: {
            'onReady': function(e) {
                yt_player.is_loaded = true;
                yt_player.playVideo();
            },
            'onStateChange': function(e) {
                switch(e.data) {
                    case YT.PlayerState.PLAYING:
                        if(yt_player.is_loaded) {
                            if(yt_events['load']) {
                                yt_events['load']();
                            }
                        }

                    break;

                    case YT.PlayerState.ENDED:
                        //yt_events['ended'] && yt_events['ended'](e);
                    break;
                }
            },
            'onError': function(e) {
                //yt_events['error'] && yt_events['error'](e);
            }
        }
    });
}

function YoutubeLoadMedia(url) {
    current_media_type = 'Youtube';

    window.onYouTubeIframeAPIReady = function() {
        window.youtube_loaded = true;
        YoutubePlayMedia(url);
    }

    if(!window.youtube_script) {
        window.youtube_script = document.createElement('script');
        window.youtube_script.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(window.youtube_script, firstScriptTag);
    } else {
        // Вече имаме api направо действаме
        YoutubePlayMedia(url);
    }
}


playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    loadRequestData => {
        if (loadRequestData.media && loadRequestData.media.contentId) {
            YoutubeLoadMedia(loadRequestData.media.contentId);
            playerManager.setMediaElement(yt_video_fake);

            return false;
        }

        return loadRequestData;
    }
);

const options = new cast.framework.CastReceiverOptions();
options.disableIdleTimeout = true;

context.start(options);