我正在研究两个相关项目,一个网页和Electron中的一个应用程序,除其他外,两者都必须播放嵌入在iframe中的Youtube视频。一切都能在网站上完美运行,
var newUrl = 'http://www.youtube.com/embed/' + $scope.youtube_parser(video.url);
$scope.videoURL = $sce.trustAsResourceUrl(newUrl + '?enablejsapi=1&showinfo=0&rel=0');
$scope.setYTPlayer();
$scope.setYTPlayer = function(){
$scope.player;
$scope.player = new YT.Player('player', {
height: '360',
width: '640',
videoId: $scope.videoSelected,
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
<iframe id="player" frameborder="0" allowfullscreen ng-src="{{videoURL}}" style="width: 100%;height: 100%;"></iframe>
但是在Electron应用程序中,许多视频都没有播放,播放器上显示一条消息:“视频不可用”
var youtubeId = $scope.getYoutubeId(video.url)
$scope.currentVideo = $sce.trustAsResourceUrl(
'https://www.youtube.com/embed/' + youtubeId + '?rel=0'
)
<iframe width="100%" height="442" ng-src="{{ currentVideo }}" frameborder="0" allowfullscreen></iframe>
页面上的相同链接使用相同的方法可以毫无问题地重现。仅尝试通过api使用iframe,更改播放参数,问题仍然存在。 问题是,是否有Youtube政策禁止在某些地方播放视频?或者是什么错误?
电子版本:v3.0.3
如果不能很好地表达自我,谢谢和道歉。
答案 0 :(得分:2)
出现此问题的原因是打开电子窗口所依据的协议。 如果打开本地html文件,则使用“ file://”协议。我找到了2个解决此问题的方法:
您可以引发本地临时http服务器,以传输窗口的html文件,然后将其禁用。
import http from 'http';
import fs from 'fs';
import path from 'path';
//at start
let server;
server = http.createServer((req, res) => {
const filePath = path.join(app.getAppPath(), 'public', req.url);
const file = fs.readFileSync(filePath);
res.end(file.toString());
if (req.url.includes('index.js'))
server.close();
}).listen(8080);
//after app-ready event
mainWindow.loadURL('http://localhost/index.html');
一个更可取的选择是拦截HTTP协议并传输文件,但是必须在传输所有本地文件后禁用拦截,否则会影响所有后续的HTTP请求。
import path from 'path';
//before window.loadURL
session.defaultSession.protocol.interceptFileProtocol('http', (request, callback) => {
const fileUrl = request.url.replace('http://localhost/', '');
const filePath = path.join(app.getAppPath(), 'public', fileUrl);
if(request.url.includes('index.js')) {
session.defaultSession.protocol.uninterceptProtocol('http');
}
callback(filePath);
});
//after app-ready event
mainWindow.loadURL('http://localhost/index.html');
此外,如果标题“ x-frame-options” =“ sameorigin”出错,则可以在收到响应后删除此标题。
const filter = {
urls: ['https://www.youtube.com/*']
};
session.defaultSession.webRequest.onHeadersReceived(filter, (details, callback) => {
for (const header in details.responseHeaders) {
if (header.toLocaleLowerCase() === 'x-frame-options') {
delete details.responseHeaders[header];
}
}
callback({ cancel: false, responseHeaders: details.responseHeaders });
});