统计
  • 建站日期:2021-03-10
  • 文章总数:10247 篇
  • 评论总数:229 条
  • 分类总数:56 个
  • 最后更新:5月17日
文章 未分类

【PHP】抖音快手短视频 图集解析PHP二创API源码

小天
首页 未分类 正文

更新时间 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 快手模拟手机端重定向

支持平台

平台 短视频 图集
ks √ √
dy √ √

效果截图

运行结果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静态文件

<!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" rel="external nofollow" ></script>
<script src="static/js/axios.min.js" rel="external nofollow" ></script>
<script src="static/js/element.js" rel="external nofollow" ></script>
<script src="static/js/vue-clipboard.min.js" rel="external nofollow" ></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 require 'API.php';

echo getUrl();

    function getUrl()
    {
        $data = API::findURL($_GET['url']);
                return  $data;
    }

    ?>
<?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: (.*?)rn/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.0 国际 (CC BY-NC-SA 4.0)》许可协议授权。
版权声明:未标注转载均为本站原创,转载时请以链接形式注明文章出处。如有侵权、不妥之处,请联系站长删除。敬请谅解!

-- 展开阅读全文 --
这篇文章最后更新于2022-8-24,已超过 1 年没有更新,如果文章内容或图片资源失效,请留言反馈,我们会及时处理,谢谢!
[Python] 下载豆瓣电影 Top 250 的海报
« 上一篇
哔哩哔哩直播签到API PHP
下一篇 »
为了防止灌水评论,登录后即可评论!

HI ! 请登录
注册会员,享受下载全站资源特权。