純前端的影視搜索網站,哄女友必備

聲明

  • 僅供學習交流,勿作他用。

CSM影視原理

  • 最開始做一個影視網站成本是很高的,需要把電影都存起來還要巨大的帶寬。近幾年影視採集站的興起,影視網站也如同雨後春筍般崛起。下圖爲市面上的cms影視站的原理
    在這裏插入圖片描述

純前端影視搜索站原理

  • 我們做的這個影視搜索網站也是建立在影視採集站的基礎之上的,通過採集站提供的API來獲取各個電影電視劇的播放地址,然後在我們的頁面嵌入一個iframe把地址放進去就能愉快的追劇了。
  • 但是我們不是通過服務器去訪問採集站的API,而是通過客戶端瀏覽器自己去發送ajax請求去訪問採集站的數據。獲取到播放地址之後直接在頁面上顯示出來。
  • 但是這裏就會涉及到跨域請求的問題了,我們的域名和採集站的域名是不一致的,js訪問會報錯。解決辦法就是在服務器端設置允許跨域訪問,可是採集站的服務器又不是我們控制的,我們該怎麼辦呢?
  • 於是我找了十幾家採集站,試了非常多的API終於找到了一個允許跨域訪問的API接口(接口地址在下面的源碼中)。下圖爲純前端影視搜索站原理。
    在這裏插入圖片描述

總體功能和框架

博主比較懶只寫了一些比較基本的功能。如果感興趣的可以複製源碼自行修改。

  • 引用類庫: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="#">&lt;</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="#">&gt;</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>&nbsp;';
	}
	$('#his_content').html(innerhtml);
}
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章