我试图建立一个铬铸造自定义接收器,以下教程在https://codelabs.developers.google.com/codelabs/cast-receiver#0我不能让它工作,不知道如何开始找出是什么问题。我已经注册了我的cast应用程序,并试图使用https://casttool.appspot.com/cactool/来测试接收器。测试适用于cactools "CC1AD845"的样品ID,它铸造良好。我还注册了我的设备进行测试,并重新启动了设备,我相信这是有效的,因为在我这样做之前,cactools不会显示我的自定义应用id的chromecast按钮,但现在它显示了。问题是,当我点击它,chrome只是显示消息:
"转换失败。请再试一次
我让我的接收器运行http-server和ngrok,就像codelabs指示的那样。我把ngrok服务器的正确路径复制到cast开发者控制台的应用URL中。
当我从浏览器中运行ngrok url时,devtools控制台显示以下错误:
Uncaught TypeError: Cannot read property 'is_device_registered' of null
at new V (caf_receiver_logger.js:18)
at Function.V.getInstance (caf_receiver_logger.js:28)
at receiver.js:13
但我相信这是由于我从浏览器打开时没有设备造成的,而在Chromecast上运行时不应该发生这种情况。
我复制了codelab提供的整个文件夹,这应该是一个自定义接收器的工作示例。但即使使用他们的确切代码,它也不起作用。代码是:
index . html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Cast CAF Receiver</title>
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<!-- Cast Debug Logger -->
<script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>
<body>
<cast-media-player></cast-media-player>
<footer>
<script src="js/receiver.js"></script>
</footer>
</body>
</html>
receiver.js
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
//Media Sample API Values
const SAMPLE_URL = "https://storage.googleapis.com/cpe-sample-media/content.json";
const StreamType = {
DASH: 'application/dash+xml',
HLS: 'application/x-mpegurl'
}
const TEST_STREAM_TYPE = StreamType.DASH
// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
castDebugLogger.setEnabled(true);
// Show debug overlay
// castDebugLogger.showDebugLogs(true);
// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}
// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
LOG_TAG: cast.framework.LoggerLevel.DEBUG,
};
function makeRequest (method, url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(JSON.parse(xhr.response));
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');
// Map contentId to entity
if (request.media && request.media.entity) {
request.media.contentId = request.media.entity;
}
return new Promise((resolve, reject) => {
// Fetch repository metadata
makeRequest('GET', SAMPLE_URL)
.then(function (data) {
// Obtain resources by contentId from downloaded repository metadata.
let item = data[request.media.contentId];
if(!item) {
// Content could not be found in repository
castDebugLogger.error(LOG_TAG, 'Content not found');
reject();
} else {
// Adjusting request to make requested content playable
request.media.contentType = TEST_STREAM_TYPE;
// Configure player to parse DASH content
if(TEST_STREAM_TYPE == StreamType.DASH) {
request.media.contentUrl = item.stream.dash;
}
// Configure player to parse HLS content
else if(TEST_STREAM_TYPE == StreamType.HLS) {
request.media.contentUrl = item.stream.hls
request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
}
castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);
// Add metadata
let metadata = new cast.framework.messages.GenericMediaMetadata();
metadata.title = item.title;
metadata.subtitle = item.author;
request.media.metadata = metadata;
// Resolve request
resolve(request);
}
});
});
});
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);
let browseItems = getBrowseItems();
function getBrowseItems() {
let browseItems = [];
makeRequest('GET', SAMPLE_URL)
.then(function (data) {
for (let key in data) {
let item = new cast.framework.ui.BrowseItem();
item.entity = key;
item.title = data[key].title;
item.subtitle = data[key].description;
item.image = new cast.framework.messages.Image(data[key].poster);
item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
browseItems.push(item);
}
});
return browseItems;
}
let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio =
cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
if (!e.value) return;
// Media browse
touchControls.setBrowseContent(browseContent);
// Clear default buttons and re-assign
touchControls.clearDefaultSlotAssignments();
touchControls.assignButton(
cast.framework.ui.ControlsSlot.SLOT_PRIMARY_1,
cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
);
});
context.start();
提前谢谢你。
is_device_registered"这个错误是由Cast Debug Logger调用引起的,它不能在浏览器中运行(因为它没有在Chromecast设备上运行,因此无法找到它)。
经过多次迭代和测试后,我注意到导致&;Failed to cast的常见原因如下。请再试一次。当使用code LABS设置时:
- Chromecast缓存应用程序数据,所以如果你更新了接收器应用程序的URL,设备必须在使用新的URL之前重新启动
- Ngrok会话超时(通过重启Ngrok并在Cast Developer Console中更新Receiver App URL解决)
- 观察您是否在http服务器控制台上看到来自Chromecast的GET请求(我的CC gen 3在用户代理中有'Linux armv71'等)。如果是这样,接收器应用程序配置正确,您的问题是代码(HTML, js等)