好友
阅读权限10
听众
最后登录1970-1-1
|
抖音快手短视频 图集解析PHP二创API源码分享
**@@Prajna ** 这是原创作者
https://www.52pojie.cn/thread-1424659-1-1.html
在这基础上进行修复 二开的
更新时间 2022/8/21 自测可用
函数说明
1、findURL平台解析
2、douyin 抖音视频处理
3、kuaishou 快手视频处理
4、httpRequest curl封装函数
5、result 返回处理6、GetBetween 截取短视频id7、get_redirect_url和qqxz_http_get重定向8、get_ks_json 快手模拟手机端重定向
支持平台
效果截图
运行结果json
{"code":200,"message":{"nickname":"卧槽这还真是我有点心动的 #头像","video_url":["https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_0.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_1.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_2.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_3.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_4.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_5.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_6.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_7.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_8.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_9.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_10.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_11.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_12.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_13.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_14.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_15.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_16.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_17.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_18.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_19.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_20.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_21.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_22.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_23.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_24.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_25.jpg","https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy_26.jpg"],"music":"https://p2.a.yximgs.com/ufile/atlas/NTE5MjM2ODk3ODQzODQ5Mzg1Ml8xNjYwNTg2ODExNDEy.m4a","type":"photo"}}
代码贴上需要static静态文件 附上github地址: https://github.com/surmoun/Short_Video-API也可以下载附件新建index.html[HTML] 纯文本查看 复制代码 <!DOCTYPE html>
<html>
<head>
<title>抖音去水印</title>
<meta name="referrer" content="never">
<meta charset="UTF-8">
<meta content='抖音,短视频,去水印,删水印,原始视频,去LOGO,删LOGO,原视频' name='Keywords'>
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<meta content='抖音一键去水印,粘贴抖音分享链接,一键获取原始视频下载地址!' itemprop='description' name='Description'>
<link rel="stylesheet" href="static/css/element.css">
<style>
body,
html {
padding: 0;
margin: 0;
background-color: #f5f5f5;
overflow: hidden;
}
* {
font-family: consolas, PingFang SC, Microsoft YaHei;
}
[v-cloak] {
visibility: hidden !important;
}
.search {
text-align: center;
padding-top: 120px;
z-index: 99;
}
.search .form {
width: 80%;
max-width: 500px;
margin-top: 30px;
}
.search .logo {
text-align: center;
display: block;
font-size: 44px;
color: #999;
font-weight: bold;
}
.search .logo img {
width: 400px;
}
.search .link {
margin-top: 20px;
}
.success {
text-align: center;
padding-top: 20px;
z-index: 99;
}
.about{
position:fixed;
right:20px;
left:20px;
bottom:30px;
text-align: center;
}
</style>
</head>
<body>
<div id="app" v-cloak v-loading.fullscreen.lock="fullscreenLoading">
<div class="search">
<div class="logo">
<font color=orangered>D</font>ouyin <font color=orangered>C</font>lear
</div>
<el-input autoFocus="true" id="keyword" ref="keyword" v-model="keyword" placeholder="请粘贴抖音复制的链接..."
class="form" size="large">
<el-button slot="append" icon="el-icon-search" @click="doPost">去水印</el-button>
</el-input>
</div>
<div class="success" v-show="successShow">
<div style="color: rgb(49, 112, 143);padding: 15px">
{{type}}
<p v-if="type=='photo'">
{{successMessage}}
<p v-if="successMessage!=' '">
<!--<img v-for="(item,i) in successMessage" :src=item style=""/>-->
</p>
</p>
<p v-if-else="type=='movie'">
{{successMessage}}
</p>
</div>
<el-button v-if="!needRefresh" type="success"><a :href="videoUrl"
style="text-decoration:none;color: #ffffff" target="_blank">查看视频</a></el-button>
<el-button v-if="needRefresh" class="copy" type="primary" v-clipboard:copy="videoUrl"
v-clipboard:success="onCopySuccess" v-clipboard:error="onCopyError">复制链接</el-button>
<el-button type="danger" @click="clear">清空</el-button>
</div>
</div>
</body>
<script src="static/js/vue-2.6.10.min.js"></script>
<script src="static/js/axios.min.js"></script>
<script src="static/js/element.js"></script>
<script src="static/js/vue-clipboard.min.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
keyword: '',
fullscreenLoading: false,
videoUrl: '',
successShow: false,
successMessage: '',
needRefresh: false,
type:''
}
},
created() {
},
updated() { },
methods: {
doPost() {
var that = this;
that.fullscreenLoading = true;
axios.post('域名/jxindex.php?url='+that.keyword)
.then(function (response) {
that.fullscreenLoading = false;
console.log(response.data);
if (response.status == 200) {
that.successShow = true;
that.videoUrl = response.data.message.video_url;
that.successMessage = response.data.message.video_url;
that.type = response.data.message.type;
that.needRefresh = false;
} else if (response.data.code == 301) {
that.successShow = true;
that.videoUrl = response.data.data;
that.successMessage = response.data.msg;
that.needRefresh = true;
} else {
that.$message.error(response.data.msg);
}
})
.
catch(function (error) {
console.log(error)
that.$message.error('出现异常,你可以控制台查看错误');
});
},
clear() {
this.keyword = '';
this.successShow = false
},
onCopySuccess(e) {
this.$message({ message: '复制成功!', type: 'success' });
},
onCopyError(e) {
this.$message.error('复制失败!');
}
}
});
</script>
</html>
调用代码[PHP] 纯文本查看 复制代码 <?php require 'API.php';
echo getUrl();
function getUrl()
{
$data = \API::findURL($_GET['url']);
return $data;
}
?>
主程序代码[PHP] 纯文本查看 复制代码 <?php
class API {
static public function findURL($url) {
// $url='';
preg_match('/([\w-]+\.)+\w+(\:\d{2,6})?/', $url, $domain);
switch ($domain[0]) {
case '':
return self::result(500, '不再提供Api测试 请前往github自行搭建 https://github.com/surmoun/Short_Video-API');
break;
case 'v.douyin.com':
return self::douyin($url);
break;
case 'v.kuaishou.com':
return self::kuaishou($url);
break;
default:
return self::result(500, '抱歉,此url暂不支持!');
}
}
static public function douyin($url) {
$url = self::httpRequest($url, 'GET');
$url = $url['location'];
// echo($url);
//模拟苹果手机访问
$UserAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1';
$d= 'https://www.douyin.com/';
$e = '/';
$flag =self::GetBetween($url,$d,$e) ;
// echo($flag);
if($flag=='video'){
$b = 'https://www.douyin.com/video/';
$c = '?p';
$id = self::GetBetween($url,$b,$c);
$vidoUrl = 'https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids='.$id;
// echo($id);
// echo($vidoUrl);
$result = self::httpRequest($vidoUrl, 'GET');
$vid = $result['response']['item_list'][0]['video']['play_addr']['uri'];
if (isset($vid)) {
$video_url = 'https://aweme.snssdk.com/aweme/v1/play/?video_id=' . $vid . '&ratio=720p&line=0';
//获取重定向后的真实地址
$video_url = self::get_redirect_url($video_url);
$music = $result['response']['item_list'][0]['music']['play_url']['uri'];
$nickname = $result['response']['item_list'][0]["share_info"]["share_title"];
$type = "movie";
$return = array('nickname' => $nickname, 'video_url' => $video_url, 'music' => $music,'type'=>$type);
return self::result(200, $return);
} else {
return self::result(500, '解析出错!');
}
}
else if($flag=='video'){
$b = 'https://www.douyin.com/note/';
$c = '?p';
$id = self::GetBetween($url,$b,$c);
$arr = json_decode(self::qqxz_http_get('https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids='. $id), true);
// var_dump($arr['item_list'][0] ["images"][2]["url_list"][0]);
// var_dump($arr['item_list'][0]["images"]);
// echo(count($arr['item_list'][0]["images"]));
// echo("<img src='$cover' type='images'");
var_dump($arr);
if ($arr) {
for($i=1;$i<count($arr['item_list'][0]["images"]);$i++){
// echo($arr['item_list'][0] ["images"][$i]["url_list"][0]);
$img[$i]=$arr['item_list'][0] ["images"][$i]["url_list"][0];
// echo("<br>");
}
$url = $arr['item_list'][0]["video"]["play_addr"]["uri"];
$title = $arr['item_list'][0]["share_info"]["share_title"];
$cover = $arr['item_list'][0]['video']["origin_cover"]["url_list"][0];
// var_dump($img);
$img[0]=$cover;
$type = "photo";
$return = array('nickname' => $title, 'video_url' => $img, 'music' => $url,'type'=>$type);
return self::result(200, $return);
} else {
return self::result(500, '解析出错!');
}
}
}
static public function kuaishou($url) {
$locs = get_headers($url, true) ['Location'][1];
// echo($locs);
$d= 'video.kuaishou.com/';
$e = '/';
$flag =self::GetBetween($locs,$d,$e) ;
// echo($flag);
preg_match('/photoId=(.*?)\&/', $locs, $matches);
// var_dump($matches[1]);
$json = self::get_ks_json($locs,$matches);
// var_dump($json['atlas']['list']);
if($flag=='short-video'){
for($i=0;$i<count($json['atlas']['list']);$i++){
$img[$i] = 'https://p2.a.yximgs.com'.$json['atlas']['list'][$i];
}
$type = 'photo';
}else{
// var_dump($json['photo']['mainMvUrls'][0]['url']);
$img = $json['photo']['mainMvUrls'][0]['url'];
$type = 'movie';
}
// var_dump( $json['shareInfo']['shareTitle']);
// var_dump( 'https://p2.a.yximgs.com'.$json['atlas']['music']);
// var_dump($img);
if ($json) {
$url = $img;
$title = $json['shareInfo']['shareTitle'];
$cover = 'https://p2.a.yximgs.com'.$json['atlas']['music'];
$return = array('nickname' => $title, 'video_url' => $url, 'music' => $cover,'type'=>$type);
// var_dump($return);
return self::result(200, $return);
} else {
return self::result(500, '解析出错!');
}
}
static public function httpRequest($url, $method = 'POST', $postfields = null, $headers = array()) {
$method = strtoupper($method);
$ci = curl_init();
curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ci, CURLOPT_TIMEOUT, 30);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, 1);
switch ($method) {
case "POST":
curl_setopt($ci, CURLOPT_POST, true);
if (!empty($postfields)) {
$tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
}
break;
default:
curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method);
break;
}
$ssl = preg_match('/^https:\/\//i', $url) ? TRUE : FALSE;
curl_setopt($ci, CURLOPT_URL, $url);
if ($ssl) {
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE);
}
curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ci, CURLOPT_MAXREDIRS, 2);
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ci, CURLINFO_HEADER_OUT, true);
$response = json_decode(curl_exec($ci), true);
$requestinfo = curl_getinfo($ci);
$http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
$location = curl_getinfo($ci, CURLINFO_EFFECTIVE_URL);
curl_close($ci);
return array('location' => $location, 'response' => $response, 'requestinfo' => $requestinfo);
}
static public function result($errno = 0, $data = '') {
header("Content-type: application/json;charset=utf-8");
$errno = intval($errno);
$result = array('code' => $errno, 'message' => $data);
return json_encode($result, 320);
}
// 截取ID
static public function GetBetween($content,$start,$end) {
$r = explode($start, $content);
if (isset($r[1])) {
$r = explode($end, $r[1]);
return $r[0];
}
return '';
}
static public function qqxz_http_get($url)
{
$Header=array( "User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1");
$con=curl_init((string)$url);
curl_setopt($con,CURLOPT_HEADER,False);
curl_setopt($con,CURLOPT_SSL_VERIFYPEER,False);
curl_setopt($con,CURLOPT_RETURNTRANSFER,true);
curl_setopt($con,CURLOPT_HTTPHEADER,$Header);
curl_setopt($con,CURLOPT_TIMEOUT,5000);
$result = curl_exec($con);
return $result;
}
static public function get_redirect_url($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array( "User-Agent:Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"));
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ret = curl_exec($ch);
curl_close($ch);
preg_match("/Location: (.*?)\r\n/iU",$ret,$location);
return $location[1];
}
static public function get_ks_json($locs,$matches) {
$headers = array('Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1','Cookie: did=web_9bceee20fa5d4a968535a27e538bf51b; didv=1655992503000;',
'Referer: ' . $locs, 'Content-Type: application/json');
$post_data = '{"photoId": "' . str_replace(['video/', '?'], '', $matches[1]) . '","isLongVideo": false}';
$vurl ='https://v.m.chenzhongtech.com/rest/wd/photo/info?kpn=KUAISHOU&captchaToken=';
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_URL, $vurl);
curl_setopt($curl, CURLOPT_NOBODY, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
$data = curl_exec($curl);
curl_close($curl);
return json_decode($data, true);
}
}
小白运行说明
1、复制代码保存API.php 复制index.html代码 保存到服务器index.html
2、复制调用示例里面的代码 保存为xjindex.php
3、放在同一个目录,假设目录为shuiyin
4、丢在服务器,域名访问 域名/shuiyin/
或者下载下面的包,解压,文件丢在服务器,按照4操作
Short_Video-API-main.zip
(348.57 KB, 下载次数: 468)
|
免费评分
-
查看全部评分
|