康巴卫视网PHP源码

原创 572 次阅读 699 字 预计阅读时间: 3 分钟 发布于 2024-12-08 最后更新于 2024-12-18


前言

最近发现,康巴卫视官网支持长达四百多天的回放,但是官网的EPG是默认的每小时一段,回放接口也是每小时一段,并不能按照正常的EPG进行自定义回放。
为了解决该痛点,本文用PHP写了提取和拼接算法,可实现指定日期中任意开始和结束时间点的回放,分享此源码以供学习参考。

源码

<?php
//Written by Wheiss
error_reporting(0);
date_default_timezone_set("PRC");
$id = isset($_GET['id'])?$_GET['id']:'kbws';
$n = [
	"kbws" => 17,//康巴卫视
];
if (!isset($n[$id])) die(header("HTTP/1.1 404"));
$playseek = $_GET['playseek']??'';
if ($playseek) {
	$t_arr = explode("-",$playseek);
	$starttime = strtotime($t_arr[0]);
	$endtime = strtotime($t_arr[1]);
	//前7天:https://mapi.kangbatv.com/api/v1/program.php?channel_id=17&zone=-6
	//当天:https://mapi.kangbatv.com/api/v1/program.php?channel_id=17&zone=0
	//前472天:https://mapi.kangbatv.com/api/v1/program.php?channel_id=17&zone=-471
	#计算起始点zone值并获取数据
	//计算开始点当天0点的时间戳
	$startDayDateOn = substr($t_arr[0],0,8).'000000';
	$startDayTimeOn = strtotime($startDayDateOn);//开始时间当天0点的时间戳
	//计算当天0点的时间戳
	$time = time();
	$nowDayDateOn = date('Ymd',$time).'000000';
	$nowDayTimeOn = strtotime($nowDayDateOn);
	$devTime = $startDayTimeOn-$nowDayTimeOn;
	$zone = floor($devTime/86400);
	$scheduleIdApi = "https://mapi.kangbatv.com/api/v1/program.php?channel_id={$n[$id]}&zone={$zone}";
	$data = get_curl($scheduleIdApi,1);
	if (!$data) {
		$data = get_curl($scheduleIdApi,2);
	}
	$allEpg = json_decode($data,TRUE);//0-23代表0点到23点的数据
	if (empty($allEpg)) die('获取epg数据失败!');
	//计算起始点时间差
	$startHDateOn = substr($t_arr[0],0,10).'0000';
	$startHTimeOn = strtotime($startHDateOn);//开始时间小时所在时间戳
	$startDevTime = $starttime-$startHTimeOn;//起始点时间差
	//计算起始点和结束点所在序号
	$endHDateOn = substr($t_arr[1],0,10).'0000';
	$endHTimeOn = strtotime($endHDateOn);//结束时间小时所在时间戳
	$startNumber = intval(($startHTimeOn-$startDayTimeOn)/3600);//起始点所在序号
	$endNumber = intval(($endHTimeOn-$startDayTimeOn)/3600);//结束点所在序号
	//计算开始点和开始小时的数据条数差,结束点和开始点的数据条数差
	$startiNumber = floor($startDevTime/5.882);
	$deviNumber = floor(($endtime-$starttime)/5.882);
	$data = '';
	for ($i = $startNumber; $i <= $endNumber; $i++) {//循环取数据
		$url = $allEpg[$i]['m3u8'];
		$data1 = get_curl($url,1);
		if (!$data1) {
			$data1 = get_curl($url,2);
		}
		if (strpos($data1,'#EXTM3U')!==FALSE) $data .= $data1;
	}
	$m3u8s = explode("\n",trim($data));
	$m3u8 = "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-MEDIA-SEQUENCE:0\n#EXT-X-TARGETDURATION:6\n";
	for ($i = 6+$startiNumber*2,$j = 0; $i < count($m3u8s)-4&&$j<$deviNumber; $i++) {
		if (strpos($m3u8s[$i],'#EXTINF')!==FALSE) {
			$m3u8 .= $m3u8s[$i]."\n";
			$i++;
			$m3u8 .= $m3u8s[$i]."\n";
			$j++;
		} elseif (strpos($m3u8s[$i],'#EXT-X-ENDLIST')!==FALSE)  {
			$i+=6;
		}
	}
	$m3u8 .= "#EXT-X-ENDLIST\n";
	$m3u8 = str_replace('../../','https://pluslive.kangbatv.com/',$m3u8);
	header('Connection: keep-alive');
	header("Content-Type: application/vnd.apple.mpegurl");
	header("Content-Disposition: inline; filename={$id}_{$t_arr[0]}_{$t_arr[1]}.m3u8");
	print_r($m3u8);
} else {
	$api = "https://mapi.kangbatv.com/api/v1/channel_detail.php?channel_id={$n[$id]}";
	$data = get_curl($api,1);
	if (!$data) $data = get_curl($api,2);
	if ($data) {
		$m3u8 = json_decode($data)[0]->channel_stream[0]->m3u8;
	} else {
		die('获取m3u8链接失败!');
	}
	header('location:'.$m3u8);
}
exit;

function get_curl($url,$timeout=1){
	$ch = curl_init($url);	
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);//跟随重定向
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);//不直接输出
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);//忽略SSL验证
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
	curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36');
	curl_setopt($ch, CURLOPT_REFERER, 'http://www.kangbatv.com/zb_22587/');
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,$timeout);
	curl_setopt($ch, CURLOPT_TIMEOUT,3);
	$data = curl_exec($ch);
	curl_close($ch);
	return $data;
}
?>

补充说明

URL格式

  • 直播示例:http://127.0.0.1/kbtv.php
  • 回放示例:http://127.0.0.1/kbtv.php?playseek=20241207213000-20241207223000