2016-04-26 65 views
8

我正在使用WebTorrent(https://webtorrent.io,https://github.com/feross/webtorrent)和使用JavaScript(Chrome)SDK的Google Cast发件人应用开发Google Cast自定义接收器应用。如何将标准媒体控件添加到Google Cast应用程序?

我的应用程序的概念是从谷歌角色发送者发送洪流ID(磁铁URI等magnet:?xt=urn:btih:6a9759bffd5c0af65319979fb7832189f4f3c35d或HTTP/HTTPS URL到像https://webtorrent.io/torrents/sintel.torrent的a *的.torrent文件)到谷歌Cast接收器,并且使用在谷歌Cast接收WebTorrent显示来自洪流的媒体(视频或音频)。

请注意,torrent ID不是媒体文件的直接URL。

现在我正在使用Google Cast名称空间和messageBus发送和接收torrent ID。

WebTorrent API提供2种方式以显示介质:使用file.appendTo

这里是我的接收器的代码:

<html> 
    <head> 
    <script src="https://www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js"></script> 
    <script src="https://cdn.jsdelivr.net/webtorrent/latest/webtorrent.min.js"></script> 
    </head> 
    <body> 
    <video autoplay id='media' /> 
    <script> 
     window.mediaElement = document.getElementById('media'); 
     window.mediaManager = new cast.receiver.MediaManager(window.mediaElement); 
     window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance(); 
     window.messageBus = window.castReceiverManager.getCastMessageBus('urn:x-cast:com.google.cast.sample.helloworld'); 
     window.messageBus.onMessage = function(event) { 
     displayVideo(event.data); 
     // Inform all senders on the CastMessageBus of the incoming message event 
     // sender message listener will be invoked 
     window.messageBus.send(event.senderId, event.data); 
     }; 
     function displayVideo(torrentId) { 
     var client = new WebTorrent(); 
     client.add(torrentId, function (torrent) { 
      var file = torrent.files[0]; 
      file.renderTo('video'); 
     }); 
     } 
     window.castReceiverManager.start(); 
    </script> 
    </body> 
</html> 

这里是我的发送者的代码:

<!-- 
Copyright (C) 2014 Google Inc. All Rights Reserved. 

Licensed under the Apache License, Version 2.0 (the "License"); 
you may not use this file except in compliance with the License. 
You may obtain a copy of the License at 

    http://www.apache.org/licenses/LICENSE-2.0 

Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
See the License for the specific language governing permissions and 
limitations under the License. 
--> 
<html> 
<head> 
<style type="text/css"> 
html, body, #wrapper { 
    height:100%; 
    width: 100%; 
    margin: 0; 
    padding: 0; 
    border: 0; 
} 
#wrapper td { 
    vertical-align: middle; 
    text-align: center; 
} 
input { 
    font-family: "Arial", Arial, sans-serif; 
    font-size: 40px; 
    font-weight: bold; 
} 
.border { 
    border: 2px solid #cccccc; 
    border-radius: 5px; 
} 
.border:focus { 
    outline: none; 
    border-color: #8ecaed; 
    box-shadow: 0 0 5px #8ecaed; 
} 
</style> 
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script> 
<script type="text/javascript"> 
var applicationID = 'F5304A3D'; 
var namespace = 'urn:x-cast:com.google.cast.sample.helloworld'; 
var session = null; 

/** 
* Call initialization for Cast 
*/ 
if (!chrome.cast || !chrome.cast.isAvailable) { 
    setTimeout(initializeCastApi, 1000); 
} 

/** 
* initialization 
*/ 
function initializeCastApi() { 
    var sessionRequest = new chrome.cast.SessionRequest(applicationID); 
    var apiConfig = new chrome.cast.ApiConfig(sessionRequest, 
    sessionListener, 
    receiverListener); 

    chrome.cast.initialize(apiConfig, onInitSuccess, onError); 
}; 

/** 
* initialization success callback 
*/ 
function onInitSuccess() { 
    appendMessage("onInitSuccess"); 
} 

/** 
* initialization error callback 
*/ 
function onError(message) { 
    appendMessage("onError: "+JSON.stringify(message)); 
} 

/** 
* generic success callback 
*/ 
function onSuccess(message) { 
    appendMessage("onSuccess: "+message); 
} 

/** 
* callback on success for stopping app 
*/ 
function onStopAppSuccess() { 
    appendMessage('onStopAppSuccess'); 
} 

/** 
* session listener during initialization 
*/ 
function sessionListener(e) { 
    appendMessage('New session ID:' + e.sessionId); 
    session = e; 
    session.addUpdateListener(sessionUpdateListener); 
    session.addMessageListener(namespace, receiverMessage); 
} 

/** 
* listener for session updates 
*/ 
function sessionUpdateListener(isAlive) { 
    var message = isAlive ? 'Session Updated' : 'Session Removed'; 
    message += ': ' + session.sessionId; 
    appendMessage(message); 
    if (!isAlive) { 
    session = null; 
    } 
}; 

/** 
* utility function to log messages from the receiver 
* @param {string} namespace The namespace of the message 
* @param {string} message A message string 
*/ 
function receiverMessage(namespace, message) { 
    appendMessage("receiverMessage: "+namespace+", "+message); 
}; 

/** 
* receiver listener during initialization 
*/ 
function receiverListener(e) { 
    if(e === 'available') { 
    appendMessage("receiver found"); 
    } 
    else { 
    appendMessage("receiver list empty"); 
    } 
} 

/** 
* stop app/session 
*/ 
function stopApp() { 
    session.stop(onStopAppSuccess, onError); 
} 

/** 
* send a message to the receiver using the custom namespace 
* receiver CastMessageBus message handler will be invoked 
* @param {string} message A message string 
*/ 
function sendMessage(message) { 
    if (session!=null) { 
    session.sendMessage(namespace, message, onSuccess.bind(this, "Message sent: " + message), onError); 
    } 
    else { 
    chrome.cast.requestSession(function(e) { 
     session = e; 
     session.sendMessage(namespace, message, onSuccess.bind(this, "Message sent: " + message), onError); 
     }, onError); 
    } 
} 

/** 
* append message to debug message window 
* @param {string} message A message string 
*/ 
function appendMessage(message) { 
    console.log(message); 
    var dw = document.getElementById("debugmessage"); 
    dw.innerHTML += '\n' + JSON.stringify(message); 
}; 

/** 
* utility function to handle text typed in by user in the input field 
*/ 
function update() { 
    sendMessage(document.getElementById("input").value); 
} 

/** 
* handler for the transcribed text from the speech input 
* @param {string} words A transcibed speech string 
*/ 
function transcribe(words) { 
    sendMessage(words); 
} 
</script> 
</head> 
<body> 
    <table id="wrapper"> 
    <tr> 
     <td> 
      <form method="get" action="JavaScript:update();"> 
       <input id="input" class="border" type="text" size="30" onwebkitspeechchange="transcribe(this.value)" x-webkit-speech/> 
      </form> 
     </td> 
    </tr> 
    </table> 

    <!-- Debbugging output --> 
    <div style="margin:10px; visibility:hidden;"> 
    <textarea rows="20" cols="70" id="debugmessage"> 
    </textarea> 
    </div> 

<script type="text/javascript"> 
    document.getElementById("input").focus(); 
</script> 
</body> 
</html> 

问题:接收器预期从发送者以及视频播放处理洪流ID。但官方的Google Cast应用或官方Google Cast for Chrome扩展程序未显示播放视频的标准媒体控件,以便暂停,停止,寻找等。

这就是我所拥有的(这是标准内置屏幕截图模态对话框,在谷歌Chrome浏览器的最新版本的谷歌演员):

Screenshot of standard built-in modal dialog for Google Cast in the latest version of Google Chrome

这是我想达到什么样的(这是标准的内置模式对话框中为谷歌投在最新版本的截图Google Chrome):

Screenshot of standard built-in modal dialog for Google Cast in the latest version of Google Chrome

添加

window.mediaElement = document.getElementById('media'); 
window.mediaManager = new cast.receiver.MediaManager(window.mediaElement); 

<video autoplay id='media' />

元素没有帮助。

我应该向发件人和/或接收者添加什么内容,以在所有发件人中为<video autoplay id='media' />添加标准媒体控件?

也许有另一种方式发送和接收洪流ID没有使用谷歌Cast命名空间和messageBus?

UPD

看起来像我发现我的问题的根源?

如何在接收器中启用现有播放视频的默认媒体控件?

例如,接收器的应用程序已经有视频播放:

<video autoplay id='media' 
src='https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4' 
/> 

如何启用默认的媒体控制 - 工作按钮“播放/暂停”,工作进度栏(像谷歌官方Cast扩充功能,为所有发件人Chrome)为这个播放视频?

貌似加入以下代码忍不住道:

window.mediaElement = document.getElementById('media'); 
window.mediaManager = new cast.receiver.MediaManager(window.mediaElement); 
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance(); 
window.castReceiverManager.start(); 

这里是接收器的全部源代码:

<html> 
<head> 
<script src="https://www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js"></script> 
</head> 
<body> 
<video autoplay id='media' 
src='https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4' 
/> 
<script> 
window.mediaElement = document.getElementById('media'); 
window.mediaManager = new cast.receiver.MediaManager(window.mediaElement); 
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance(); 
window.castReceiverManager.start(); 
</script> 
</body> 
</html> 

UPD2:

看起来是可能的在chrome.cast.media.MediaInfo中使用任何文本字符串(在我的情况下,洪流ID),而不是媒体网址,并使用媒体命名空间,而不是使用自定义命名空间和自定义消息总线(即不使用https://developers.google.com/cast/docs/reference/receiver/cast.receiver.CastReceiverManager#getCastMessageBushttps://developers.google.com/cast/docs/reference/receiver/cast.receiver.CastMessageBushttps://developers.google.com/cast/docs/reference/chrome/chrome.cast.Session#sendMessage):

function cast() { 
    url = 'magnet:?xt=urn:btih:6a9759bffd5c0af65319979fb7832189f4f3c35d'; 
    chrome.cast.requestSession(function(session) { 
    var mediaInfo = new chrome.cast.media.MediaInfo(url); 
    //mediaInfo.contentType = 'video/mp4'; 
    //mediaInfo.contentType = 'audio/mpeg'; 
    //mediaInfo.contentType = 'image/jpeg'; 
    var request = new chrome.cast.media.LoadRequest(mediaInfo); 
    request.autoplay = true; 
    session.loadMedia(request, function() {}, onError); 
    }, onError); 
} 

但如何处理它在这种情况下,接收器?

回答

1

实际上存在一个现有的Google Cast UX指南,其中规定发件人应用程序必须提供顶级投射按钮。有支持的钮扣这是在Android Sender App Development

  • 使用MediaRouter动作条提供充分的讨论三种方式: android.support.v7.app.MediaRouteActionProvider
  • 使用MediaRouter演员按钮: android.support .v7.app.MediaRouteButton
  • 开发与MediaRouter API和 MediaRouter.Callback自定义UI

要显示标准媒体CON当媒体播放时,发送者应用程序可以使用RemoteMediaPlayer实例控制媒体播放。步骤和示例可以在文档中找到。

有关Google Cast Android SDK中所有类,方法和事件的完整列表,请参见Google Cast Android API Reference

+0

感谢您的回复,但是关于开发JavaScript(Chrome)Google Cast发件人(https://developers.google.com/cast/docs/chrome_sender)而不是Android发件人的问题。 –

+0

用于发送与Android相关的文档而不是JavasScript的道歉。无论如何,感谢您编辑您的文章和标记JavaScript。 :) – Teyam