聲明
- 僅供學習交流,勿作他用。
CSM影視原理
- 最開始做一個影視網站成本是很高的,需要把電影都存起來還要巨大的帶寬。近幾年影視采集站的興起,影視網站也如同雨後春筍般崛起。下圖為市面上的cms影視站的原理
純前端的影視搜尋網站,哄女友必備聲明CSM影視原理純前端影視搜尋站原理總體功能和架構源碼
純前端影視搜尋站原理
- 我們做的這個影視搜尋網站也是建立在影視采集站的基礎之上的,通過采集站提供的API來擷取各個電影電視劇的播放位址,然後在我們的頁面嵌入一個iframe把位址放進去就能愉快的追劇了。
- 但是我們不是通過伺服器去通路采集站的API,而是通過用戶端浏覽器自己去發送ajax請求去通路采集站的資料。擷取到播放位址之後直接在頁面上顯示出來。
- 但是這裡就會涉及到跨域請求的問題了,我們的域名和采集站的域名是不一緻的,js通路會報錯。解決辦法就是在伺服器端設定允許跨域通路,可是采集站的伺服器又不是我們控制的,我們該怎麼辦呢?
- 于是我找了十幾家采集站,試了非常多的API終于找到了一個允許跨域通路的API接口(接口位址在下面的源碼中)。下圖為純前端影視搜尋站原理。
純前端的影視搜尋網站,哄女友必備聲明CSM影視原理純前端影視搜尋站原理總體功能和架構源碼
總體功能和架構
部落客比較懶隻寫了一些比較基本的功能。如果感興趣的可以複制源碼自行修改。
- 引用類庫:bootstrap4、jquery3.5
- 基本UI設計:搜尋框、搜尋按鈕、曆史記錄标簽、播放劇集清單、視訊播放區域。
- 功能實作:影視搜尋、搜尋敏感詞過濾、播放選集、上一集下一集、本地儲存曆史播放記錄
- 示範站點:http://www.kubuku.cool/
源碼
- 為了友善新手看得明白,部落客在關鍵的地方都加了注釋。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>酷不酷影視</title>
<script src="https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<!-- 頭部的搜尋區域開始 -->
<div class="card text-center">
<div class="card-header">
酷不酷影視
</div>
<div class="card-body">
<p class="card-text"><input onkeypress="if(event.keyCode==13){search()}" placeholder="請輸入你要看的電影/電視劇" class="form-control form-control-lg" id='wd'/></p>
<button class="btn btn-primary" onclick="search()">搜尋</button>
<p class="card-text" id="his_content"></p>
</div>
</div>
<!-- 頭部的搜尋區域結束 -->
<!-- 中間的播放器區域開始(預設不顯示) -->
<div class="container" id="play" style="display:None">
<div class="row" id="play_name">
</div>
<div class="row">
<iframe id="playframe"
src=""
allowfullscreen="true"
width="100%"
>
</iframe>
</div>
<div class="row">
<div class="col">
<a class="page-link" onclick="lastone()" href="#"><</a>
</div>
<div class="col"></div><div class="col"></div><div class="col"></div><div class="col"></div><div class="col"></div><div class="col"></div><div class="col"></div><div class="col"></div><div class="col"></div>
<div class="col">
<a class="page-link" onclick="nextone()" href="#">></a>
</div>
</div>
</div>
<!-- 中間的播放器區域結束 -->
<!-- 按搜尋按鈕時會出現下面的這個轉圈圈的加載動畫 -->
<div id="spinner" class="spinner-border" role="status" style="display:None">
<span class="sr-only">Loading...</span>
</div>
<!-- 搜尋的結果和選集的div -->
<div id="vod_name">
</div>
<div id="list">
</div>
</body>
</html>
<script>
// 定義全局對象,搜尋出來的json資料清單,播放曆史資料清單,目前播放的vod對象
vodlist = [];
hislist = [];
currvod = {};
//搜尋加載資料時,顯示這個加載的圈圈
function spinLoad(action){
if(action){
$('#spinner').attr('style','');
}else{
$('#spinner').attr('style','display:None');
}
}
//清空播放清單
function init(){
$('#list').html('');
$('#vod_name').html('');
}
//根據關鍵詞搜劇
function search(){
//如果關鍵字為空就直接傳回
var wd = $('#wd').val();
if(wd==null || wd=="" || wd=='undefined'){
return false;
}
init();//清空播放清單
spinLoad(true);//顯示加載的圈圈
//開始發送ajax請求搜尋影視
$.ajax({ url: "https://api.okzy.tv/api.php/provide/vod/at/json/?ac=detail&wd="+wd,
dataType:"json",
success: function(data){
vodlist = data.list;
//将傳回的資料拼接html渲染到頁面
innerhtml = "<ul class=\"list-group\">";
for(var i=0;i<vodlist.length;i++){
//屏蔽詞
if(vodlist[i].vod_name.indexOf("日韓") == -1){
innerhtml += '<li class=\"list-group-item\"><a οnclick="playvodlist('+vodlist[i].vod_id+')">' + vodlist[i].vod_name + '</a></li>';
}
}
innerhtml += "</ul>";
$('#list').html(innerhtml);
spinLoad(false);//關閉加載的圈圈
}
});
}
//根據id列出這部劇的播放清單(集數)
function playvodlist(vid) {
//這個方法是從搜尋的結果中選中了一個,然後要展示劇集
init();
var vod_play_url = "";
var currvod = {};
var vod = {};
vod.playlist=[];
//把播放位址拿出來
for (var i=0;i<vodlist.length;i++)
{
if(vodlist[i].vod_id == vid){
vod_play_url = vodlist[i].vod_play_url;
currvod = vodlist[i];
break;
}
}
vod.vod_id = currvod.vod_id;
vod.vod_name = currvod.vod_name;
vod.progress = 0;
$('#vod_name').html(vod.vod_name);
vod_play_url += "";
vod_play_url = vod_play_url.split('$$$')[0].split('#');
innerhtml = "<ol class=\"list-group\">";
for(var i=0; i<vod_play_url.length;i++){
v = vod_play_url[i].split('$');
url = encodeURIComponent(v[1]);
url = url.trim();
innerhtml += '<li class=\"list-group-item\"><a οnclick=\'playvod(\"'+vod.vod_id+'\",\"'+i+'\")\'>' + v[0] + '</a></li>';
var obj={};
obj.name = v[0];
obj.url = url;
vod.playlist.push(obj);
}
innerhtml += "</ol>";
$('#list').html(innerhtml);
addhistory(vod);//儲存這個播放的對象到曆史記錄清單中
}
//添加到曆史播放記錄中
function addhistory(vod){
for(var v of hislist) {
if(v.vod_id == vod.vod_id){
return;
}
}
// 最多隻保留3條播放記錄
if(hislist.length>4){
hislist.pop();
}
hislist.splice(0, 0, vod);
writelocal();
}
//将播放曆史寫入本地
function writelocal(){
localStorage.setItem('hislist',JSON.stringify(hislist));
}
//更新播放進度
function updateprogress(vid,progress){
var vod = findvod(vid);
vod.progress = progress;
writelocal();
}
//根據id從曆史記錄清單對象中查找電視劇
function findvod(vid){
var vod = {};
for(var i=0; i<hislist.length;i++){
if(hislist[i].vod_id==vid){
vod = hislist[i];
break;
}
}
return vod;
}
//根據電視劇id和集數來播放電視
function playvod(vid,progress){
var vod = findvod(vid);
currvod = vod;
progress = parseInt(progress);
$('#play_name').html("正在播放:"+vod.vod_name+"----"+vod.playlist[progress].name);
//有些url是m3u8字尾的,有些又不是,需要分别判斷一下
url = decodeURIComponent(vod.playlist[progress].url);
if(url.indexOf(".m3u8") != -1){
url = 'https://www.playm3u8.cn/jiexi.php?url='+url;
}
$('#play').attr('style','');
$('#playframe').attr('src',url);
updateprogress(vid,progress);
updatehisUI();
updateplaylistUI();
}
//上一集
function lastone(){
if(currvod.progress==0){
progress = 0;
}else{
progress = currvod.progress-1;
}
playvod(currvod.vod_id,progress);
}
//下一集
function nextone(){
if(currvod.progress==currvod.playlist.length-1){
progress = currvod.playlist.length-1;
}else{
progress = currvod.progress+1;
}
playvod(currvod.vod_id,progress);
}
//頁面加載時自動加載上次儲存的曆史記錄
$(document).ready(function() {
$('#play').contents().find('body').attr('oncontextmenu',"javascript:return false;");
$(document).bind("contextmenu",function(e) {
return false;
});
vodlist = [];
hislist = localStorage.getItem('hislist')==null?[]:JSON.parse(localStorage.getItem('hislist'));
updatehisUI();
});
//更新播放清單的UI
function updateplaylistUI(){
innerhtml = "<ol class=\"list-group\">";
for(var i=0; i<currvod.playlist.length;i++){
innerhtml += '<li class=\"list-group-item\"><a οnclick=\'playvod(\"'+currvod.vod_id+'\",\"'+i+'\")\'>' + currvod.playlist[i].name + '</a></li>';
}
innerhtml += "</ol>";
$('#list').html(innerhtml);
}
//更新曆史記錄的UI
function updatehisUI(){
innerhtml = '';
for(var i=0; i<hislist.length;i++){
innerhtml += '<a class="badge badge-success" οnclick=\'playvod(\"'+hislist[i].vod_id+'\",\"'+hislist[i].progress+'\")\'>'+hislist[i].vod_name+'</a> ';
}
$('#his_content').html(innerhtml);
}
</script>