我正在使用WebTorrent (https://webtorrent.io,https://github.com/feross/webtorrent)开发Google定制接收器应用程序,使用JavaScript (Chrome) SDK开发Google发送者应用程序。
我的应用程序的想法是从Google发件人向Google接收器发送torrent id (magnet,如magnet:?xt=urn:btih:6a9759bffd5c0af65319979fb7832189f4f3c35d
或HTTP/HTTPS到*.torrent文件,如https://webtorrent.io/torrents/sintel.torrent
),并使用Google接收器中的WebTorrent来显示来自洪流的媒体(视频或音频)。
注意,torrent id不是媒体文件的直接URL。
现在,我使用Google命名空间和messageBus来发送和接收torrent id。
WebTorrent API提供了2种显示媒体的方法:
file.appendTo
:https://webtorrent.io/docs#-file-appendto-rootelem-function-callback-err-elem-将其附加到DOM中file.renderTo
:https://webtorrent.io/docs#-file-renderto-elem-function-callback-err-elem-直接呈现给给定元素(或CSS选择器)这是我的接收器的代码:
<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应用程序或Chrome的官方Google扩展并不显示播放视频的标准媒体控件来暂停、停止、查找等等。
这就是我所拥有的(这是Google最新版本Google标准内置模式对话框的屏幕截图):
这就是我想要实现的目标(这是最新版本的Google中Google Cast标准内置模式对话框的屏幕截图):
添加
window.mediaElement = document.getElementById('media');
window.mediaManager = new cast.receiver.MediaManager(window.mediaElement);
为
<video autoplay id='media' />
元素不起作用。
我是否应该向发送方和/或接收方添加一些内容,以便在所有发件人上为<video autoplay id='media' />
添加标准媒体控件?
也许还有另一种方式可以不使用Google命名空间和messageBus来发送和接收流id?
UPD
看来我找到了问题的根源..。
如何为接收器中现有的播放视频启用默认媒体控件?
例如,接收应用程序已经播放了视频:
<video autoplay id='media'
src='https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'
/>
如何启用默认媒体控件-工作按钮“播放/暂停”,工作进度条(在所有发送者,如官方谷歌抛出的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
中使用任何文本字符串(在我的例子中是torrent id )来代替媒体URL,并且可以使用媒体名称空间而不是使用自定义名称空间和自定义消息总线(即不使用https://developers.google.com/cast/docs/reference/receiver/cast.receiver.CastReceiverManager#getCastMessageBus、https://developers.google.com/cast/docs/reference/receiver/cast.receiver.CastMessageBus和https://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);
}
但是在这种情况下,如何在听筒上处理呢?
发布于 2016-04-27 15:12:43
实际上,有一个现有的Google指南,其中规定发件人应用程序必须提供一个顶级的强制转换按钮。有三种支持强制按钮的方法,这在Android发件人应用程序开发中得到了充分的讨论
要显示媒体播放后的标准媒体控件,发送方应用程序可以使用RemoteMediaPlayer实例控制媒体回放。步骤和示例可以在文档中找到。
有关Google中所有类、方法和事件的全面列表,请参阅Google参考。
发布于 2019-12-23 09:56:38
我意识到已经三年了,但我突然发现你错过了视频标签上的“控件”属性!如果没有该属性,播放器将呈现视频,但不提供控制播放的ui .
语法与自动播放相同: controls属性是独立的,不带值。这是全部或完全没有-一套标准的控件与默认样式,或根本没有.如果您是为浏览器构建的,您可以选择省略属性并创建自己的控件以匹配页面的外观和感觉。但是根据您共享的屏幕截图,没有必要(而且它可能在chromecast接收器环境中不起作用)
正确的html如下所示,这应该是您所需要的:)
https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4‘/>
请告诉我们你是否和如何解决了你的问题(给我发个DM.我最近开始将webtorrent集成到我正在创建的流媒体视频平台中,到目前为止还不错,但是文档非常糟糕,我有几个问题。谢谢!)
https://stackoverflow.com/questions/36863154
复制相似问题