skipFirstPage; } public function setSkipFirstPage(bool $skipFirstPage): void { $this->skipFirstPage = $skipFirstPage; } private $mixinKeyEncTab = [ 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52, ]; protected $repository; protected $client; public function __construct(BilibiliVideoRepository $repository) { $this->repository = $repository; $maxRetries = 3; $decider = function (int $retries, RequestInterface $request, ResponseInterface $response = null) use ($maxRetries): bool { return $retries < $maxRetries && null !== $response && 429 === $response->getStatusCode(); }; $delay = function (int $retries, ResponseInterface $response): int { if (!$response->hasHeader('Retry-After')) { return RetryMiddleware::exponentialDelay($retries); } $retryAfter = $response->getHeaderLine('Retry-After'); if (!is_numeric($retryAfter)) { $retryAfter = (new DateTime($retryAfter))->getTimestamp() - time(); } return (int) $retryAfter * 1000; }; $stack = HandlerStack::create(); $stack->push(Middleware::retry($decider, $delay)); $this->client = new Client(['handler' => $stack]); } public function queryPlayList() { $pageNo = 1; $url = "https://space.bilibili.com/ajax/member/getSubmitVideos?mid=391073761&pagesize=30&tid=0&keyword=&order=pubdate&page="; for ($i = 1; $i < 30; $i++) { # code... $result = json_decode(file_get_contents($url . $i), true); foreach ($result['data']['vlist'] as $item) { echo "av" . $item['aid'] . " "; } // echo $result['data']['vlist'][0]['aid'] . "\t"; // $pageNo++; } } /** * 获取各个 up 主的视频 id * @param int $mediaId * @throws Exception */ public function queryUpVideoList($mediaId = 320491072, $startPos = 0, $limit = 20) { Log::info("schedule queryUpVideoList inner started at: " . date("Y-m-d H:i:s")); // 475250 kyokyo // 3489535 熊小颖 // 320491072 绯绯 // 10139490 短短 // 116683 咬人猫 // 16539048 小仙若 // 10278125 香草猫饼 // 391073761 女团直拍 // 267781236 韩国女团饭拍直拍 // 23400436 小雪_juvia $list = BilibiliUpVideos::where("id", "<=", "150") ->orderBy('id', 'desc') ->offset($startPos) ->limit($limit) ->get(); // $list = $list->slice(5); foreach ($list as $key => $item) { Log::info("schedule queryUpVideoList current up is {$item['up_name']}, started at: " . date("Y-m-d H:i:s")); // $files = scandir($this->baseDir . "bilibili/" . $item['up_name']); // $todayCount = $this->queryUpVideoTotalWithCache($item["mid"]); $todayCount = 1000; if ($todayCount <= $item["count"]) { Log::info("today new count is {$todayCount} is same or smaller than {$item["count"]} skip"); continue; } $mediaId = $item['mid']; $videos = []; $pageNo = 1; $url = "https://api.bilibili.com/x/space/wbi/arc/search?mid={$mediaId}&ps=30&tid=0&keyword=&pn="; $pageAll = ceil(($todayCount - $item["count"]) / 30); // if ($mediaId == 241804522 || $mediaId == 3461581333596856) { // $pageAll = 10; // } // https://api.bilibili.com/x/space/wbi/arc/search? // mid=363430107& //ps=30& //tid=0& //pn=1& //keyword=& //order=pubdate& //platform=web& //web_location=1550101& //order_avoided=true& //w_rid=a1011501119a6d795f369ec2bafa1af2& //wts=1685087658 // https://space.bilibili.com/475250/video for ($i = 1; $i <= $pageAll; $i++) { $curl = curl_init(); $b_nut = time(); $dmImgStr = str_replace("==", "", base64_encode($this->randFloat())); $dmImgStr = "V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ"; $dmCoverImgStr = str_replace("==", "", base64_encode($this->randFloat())); $dmCoverImgStr = "QU5HTEUgKEludGVsIEluYy4sIEludGVsKFIpIElyaXMoVE0pIFBsdXMgR3JhcGhpY3MgNjU1LCBPcGVuR0wgNC4xKUdvb2dsZSBJbmMuIChJbnRlbCBJbmMuKQ"; // echo $dmImgStr . "\n"; // echo $dmCoverImgStr . "\n";exit; $dm_rand = 'ABCDEFGHIJK'; $dm_img_list = '[]'; $dm_img_str = $this->GetRandStr(2); $dm_cover_img_str = $this->GetRandStr(2); $dm_img_inter = "{\"ds\":[],\"wh\":[0,0,0],\"of\":[0,0,0]}"; $w_webid = $this->getWebId(); $encrypt_string = "dm_img_list={$dm_img_list}&dm_img_str={$dm_img_str}&dm_cover_img_str={$dm_cover_img_str}&dm_img_inter=" . $dm_img_inter . "&w_webid={$w_webid}&keyword=&mid={$mediaId}&order=pubdate&order_avoided=true&platform=web&pn={$i}&ps=30&tid=&web_location="; $query = $this->build_params($encrypt_string); // dump($query);exit; $params = [ "mid" => $mediaId, "ps" => 30, "tid" => '', "keyword" => "", "order" => "pubdate", "platform" => "web", "web_location" => 1550101, "order_avoided" => 'true', "pn" => $i, "dm_img_list" => [], "dm_img_str" => $dmImgStr, "dm_cover_img_str" => $dmCoverImgStr, ]; // $query = $this->build_params($params); // echo $query;exit; // $opts = array('http' => array('header' => '"User-Agent": "Mozilla/5.0"\r\n "origin": "https://space.bilibili.com\r\n "accept-language":"en,zh-CN;q=0.9,zh;q=0.8"\r\n')); // $ctx = stream_context_create($opts); // echo file_get_contents("https://api.bilibili.com/x/space/wbi/arc/search?" . $query["new"], false, $ctx); // exit; $url = "https://api.bilibili.com/x/space/wbi/arc/search?" . $query["new"]; $header[] = "Accept: */*"; $header[] = "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"; $header[] = "Connection: close"; $header[] = "Cache-Control: max-age=0"; // $header[] = "Cookie: buvid3=F1D75200-6E4F-58D2-E1FA-7DE70663401985249infoc; b_nut=1706932685; buvid4=A11F8D72-D362-0ECD-5199-D0E4F52EE6F285597-024020303-jL3QxKOpdP9YTu%2BHyZaEIQ%3D%3D; _uuid=449728D2-B68B-1026D-DBB2-A1BEDCC6866585496infoc; buvid_fp=0be21f013c19ab3635b096b34a8a20fd; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDcxOTE4ODYsImlhdCI6MTcwNjkzMjYyNiwicGx0IjotMX0.KdU9NjwlEAoUr2VXRehVM4omOfSN1Wh9KPn0Cp_Fhtw; bili_ticket_expires=1707191826; b_lsid=6F6684EC_18D6EBB74D7; PVID=1"; curl_setopt_array($curl, [ CURLOPT_HTTPGET => 1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => 1, CURLOPT_HTTPHEADER => $header, CURLOPT_ENCODING => '', CURLOPT_URL => $url, CURLOPT_USERAGENT => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', CURLOPT_TIMEOUT => 15, ]); // curl_setopt_array($curl, array( // CURLOPT_URL => "https://api.bilibili.com/x/space/wbi/arc/search?" . $query["new"], // CURLOPT_RETURNTRANSFER => true, //// CURLOPT_ENCODING => '', //// CURLOPT_MAXREDIRS => 10, //// CURLOPT_TIMEOUT => 10, //// CURLOPT_FOLLOWLOCATION => true, //// CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, // CURLOPT_CUSTOMREQUEST => 'GET', // CURLOPT_HTTPHEADER => array( //// 'authority' => 'api.bilibili.com', //// 'accept' => '*/*', //// 'accept-language' => 'en,zh-CN;q=0.9,zh;q=0.8', //// 'cache-control' => 'no-cache', // 'origin' => 'https://space.bilibili.com', //// 'pragma' => 'no-cache', //// 'referer' => 'https://space.bilibili.com/385079033/', //// 'sec-ch-ua' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', //// 'sec-ch-ua-mobile' => '?0', //// 'sec-ch-ua-platform' => '"macOS"', //// 'sec-fetch-dest' => 'empty', //// 'sec-fetch-mode' => 'cors', //// 'sec-fetch-site' => 'same-site', // 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'), // )); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response;exit; $result = json_decode($response, true); if (!array_key_exists("data", $result) || !array_key_exists("list", $result["data"])) { Log::info("result is null " . json_encode($response)); exit; continue; } $count = Arr::get(Arr::get($result["data"], "page", []), "count", 0); Log::info("up {$item["up_name"]} count is {$count}"); $result = Arr::get($result["data"]["list"], "vlist", []); if (count($result) > 0) { // && $count > $item["count"] + ($i - 1) * 30 foreach ($result as $vItem) { $bVideo = BilibiliVideos::firstOrCreate(["aid" => $vItem["aid"]], [ "title" => $vItem["title"], "from_type" => 2, "from_up_name" => $item["up_name"], "bv_id" => $vItem["bvid"], "up_mid" => $mediaId, "collection_mid" => 0, ]); if ($bVideo->from_type != 2) { $bVideo->from_type = 3; } $bVideo->bv_id = $vItem["bvid"]; $bVideo->up_mid = $mediaId; $bVideo->from_up_name = $item["up_name"]; $bVideo->save(); $videos[] = $vItem["aid"]; } } else { break; } } usleep(random_int(1000, 10000) * 1000); } if ($key % 5 == 0 && $key != 0) { sleep(300); } if (isset($count) && $count > $item["count"]) { $item["count"] = $count; } // $item['videos'] = json_encode($videos); // $item['downloaded_videos'] = json_encode([]); $item->save(); } } public function queryUpVideoListNew($mediaId = 320491072, $startPos = 0, $limit = 20) { Log::info("schedule queryUpVideoList inner started at: " . date("Y-m-d H:i:s")); // 475250 kyokyo // 3489535 熊小颖 // 320491072 绯绯 // 10139490 短短 // 116683 咬人猫 // 16539048 小仙若 // 10278125 香草猫饼 // 391073761 女团直拍 // 267781236 韩国女团饭拍直拍 // 23400436 小雪_juvia $list = BilibiliUpVideos::where("id", "<=", "200") ->orderBy('id', 'desc') ->offset($startPos) ->limit($limit) ->get(); // $list = $list->slice(5); foreach ($list as $key => $item) { Log::info("schedule queryUpVideoList current up is {$item['up_name']}, started at: " . date("Y-m-d H:i:s")); // $files = scandir($this->baseDir . "bilibili/" . $item['up_name']); // $todayCount = $this->queryUpVideoTotalWithCache($item["mid"]); $todayCount = 1000; if ($todayCount <= $item["count"]) { Log::info("today new count is {$todayCount} is same or smaller than {$item["count"]} skip"); continue; } $mediaId = $item['mid']; $videos = []; $pageNo = 1; $url = "https://api.bilibili.com/x/space/wbi/arc/search?mid={$mediaId}&ps=30&tid=0&keyword=&pn="; $pageAll = ceil(($todayCount - $item["count"]) / 30); // if ($mediaId == 241804522 || $mediaId == 3461581333596856) { // $pageAll = 10; // } // https://api.bilibili.com/x/space/wbi/arc/search? // mid=363430107& //ps=30& //tid=0& //pn=1& //keyword=& //order=pubdate& //platform=web& //web_location=1550101& //order_avoided=true& //w_rid=a1011501119a6d795f369ec2bafa1af2& //wts=1685087658 // https://space.bilibili.com/475250/video for ($i = 1; $i <= $pageAll; $i++) { $curl = curl_init(); $b_nut = time(); $dmImgStr = str_replace("==", "", base64_encode($this->randFloat())); $dmImgStr = "V2ViR0wgMS4wIChPcGVuR0wgRVMgMi4wIENocm9taXVtKQ"; $dmCoverImgStr = str_replace("==", "", base64_encode($this->randFloat())); $dmCoverImgStr = "QU5HTEUgKEludGVsIEluYy4sIEludGVsKFIpIElyaXMoVE0pIFBsdXMgR3JhcGhpY3MgNjU1LCBPcGVuR0wgNC4xKUdvb2dsZSBJbmMuIChJbnRlbCBJbmMuKQ"; // echo $dmImgStr . "\n"; // echo $dmCoverImgStr . "\n";exit; $dm_rand = 'ABCDEFGHIJK'; $dm_img_list = '[]'; $dm_img_str = $this->GetRandStr(2); $dm_cover_img_str = $this->GetRandStr(2); $dm_img_inter = "{\"ds\":[],\"wh\":[0,0,0],\"of\":[0,0,0]}"; $w_webid = $this->getWebId(); $encrypt_string = "dm_img_list={$dm_img_list}&dm_img_str={$dm_img_str}&dm_cover_img_str={$dm_cover_img_str}&dm_img_inter=" . $dm_img_inter . "&w_webid={$w_webid}&keyword=&mid={$mediaId}&order=pubdate&order_avoided=true&platform=web&pn={$i}&ps=30&tid=&web_location="; $query = $this->build_params($encrypt_string); // dump($query);exit; $params = [ "mid" => $mediaId, "ps" => 30, "tid" => '', "keyword" => "", "order" => "pubdate", "platform" => "web", "web_location" => 1550101, "order_avoided" => 'true', "pn" => $i, "dm_img_list" => [], "dm_img_str" => $dmImgStr, "dm_cover_img_str" => $dmCoverImgStr, ]; // $query = $this->build_params($params); // echo $query;exit; // $opts = array('http' => array('header' => '"User-Agent": "Mozilla/5.0"\r\n "origin": "https://space.bilibili.com\r\n "accept-language":"en,zh-CN;q=0.9,zh;q=0.8"\r\n')); // $ctx = stream_context_create($opts); // echo file_get_contents("https://api.bilibili.com/x/space/wbi/arc/search?" . $query["new"], false, $ctx); // exit; $url = "https://api.bilibili.com/x/space/wbi/arc/search?" . $query["new"]; $header[] = "Accept: */*"; $header[] = "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"; $header[] = "Connection: close"; $header[] = "Cache-Control: max-age=0"; // $header[] = "Cookie: buvid3=F1D75200-6E4F-58D2-E1FA-7DE70663401985249infoc; b_nut=1706932685; buvid4=A11F8D72-D362-0ECD-5199-D0E4F52EE6F285597-024020303-jL3QxKOpdP9YTu%2BHyZaEIQ%3D%3D; _uuid=449728D2-B68B-1026D-DBB2-A1BEDCC6866585496infoc; buvid_fp=0be21f013c19ab3635b096b34a8a20fd; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDcxOTE4ODYsImlhdCI6MTcwNjkzMjYyNiwicGx0IjotMX0.KdU9NjwlEAoUr2VXRehVM4omOfSN1Wh9KPn0Cp_Fhtw; bili_ticket_expires=1707191826; b_lsid=6F6684EC_18D6EBB74D7; PVID=1"; curl_setopt_array($curl, [ CURLOPT_HTTPGET => 1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => 1, CURLOPT_HTTPHEADER => $header, CURLOPT_ENCODING => '', CURLOPT_URL => $url, CURLOPT_USERAGENT => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', CURLOPT_TIMEOUT => 15, ]); // curl_setopt_array($curl, array( // CURLOPT_URL => "https://api.bilibili.com/x/space/wbi/arc/search?" . $query["new"], // CURLOPT_RETURNTRANSFER => true, //// CURLOPT_ENCODING => '', //// CURLOPT_MAXREDIRS => 10, //// CURLOPT_TIMEOUT => 10, //// CURLOPT_FOLLOWLOCATION => true, //// CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, // CURLOPT_CUSTOMREQUEST => 'GET', // CURLOPT_HTTPHEADER => array( //// 'authority' => 'api.bilibili.com', //// 'accept' => '*/*', //// 'accept-language' => 'en,zh-CN;q=0.9,zh;q=0.8', //// 'cache-control' => 'no-cache', // 'origin' => 'https://space.bilibili.com', //// 'pragma' => 'no-cache', //// 'referer' => 'https://space.bilibili.com/385079033/', //// 'sec-ch-ua' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36', //// 'sec-ch-ua-mobile' => '?0', //// 'sec-ch-ua-platform' => '"macOS"', //// 'sec-fetch-dest' => 'empty', //// 'sec-fetch-mode' => 'cors', //// 'sec-fetch-site' => 'same-site', // 'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'), // )); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response;exit; $result = json_decode($response, true); if (!array_key_exists("data", $result) || !array_key_exists("list", $result["data"])) { Log::info("result is null " . json_encode($response)); exit; continue; } $count = Arr::get(Arr::get($result["data"], "page", []), "count", 0); Log::info("up {$item["up_name"]} count is {$count}"); $result = Arr::get($result["data"]["list"], "vlist", []); if (count($result) > 0) { // && $count > $item["count"] + ($i - 1) * 30 foreach ($result as $vItem) { $bVideo = BilibiliVideos::firstOrCreate(["aid" => $vItem["aid"]], [ "title" => $vItem["title"], "from_type" => 2, "from_up_name" => $item["up_name"], "bv_id" => $vItem["bvid"], "up_mid" => $mediaId, "collection_mid" => 0, ]); if ($bVideo->from_type != 2) { $bVideo->from_type = 3; } $bVideo->bv_id = $vItem["bvid"]; $bVideo->up_mid = $mediaId; $bVideo->from_up_name = $item["up_name"]; $bVideo->save(); $videos[] = $vItem["aid"]; } } else { break; } } usleep(random_int(1000, 10000) * 1000); } if ($key % 5 == 0 && $key != 0) { sleep(300); } if (isset($count) && $count > $item["count"]) { $item["count"] = $count; } // $item['videos'] = json_encode($videos); // $item['downloaded_videos'] = json_encode([]); $item->save(); } } public function queryUpVideoTotalWithCache($mid) { $today = date("Y-m-d"); $todayCount = Redis::connection()->get("bilibili:count:{$today}:{$mid}"); if ($todayCount == null) { $todayCount = $this->queryUpVideoTotal($mid); Redis::connection()->set("bilibili:count:{$today}:{$mid}", $todayCount); } return $todayCount; } /** * @throws Exception */ public function queryUpVideoTotal($mid) { $url = "https://api.bilibili.com/x/space/navnum?mid=" . $mid; $curl = curl_init(); $header[] = "Accept: */*"; $header[] = "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"; $header[] = "Connection: close"; $header[] = "Cache-Control: max-age=0"; curl_setopt_array($curl, [ CURLOPT_HTTPGET => 1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => 1, CURLOPT_HTTPHEADER => $header, CURLOPT_ENCODING => '', CURLOPT_URL => $url, CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36 Edg/102.0.1245.39', CURLOPT_TIMEOUT => 15, ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { echo $response; $res = json_decode($response, true); if (array_key_exists("data", $res) && array_key_exists("video", $res["data"])) { return $res["data"]["video"]; } else { throw new Exception("获取up 视频数量异常"); } } } /** * 手动执行查询 * @param int $mediaId * @throws Exception */ public function queryLocalUpVideoList($mediaId = 320491072) { Log::info("schedule queryUpVideoList inner started at: " . date("Y-m-d H:i:s")); // 475250 kyokyo // 3489535 熊小颖 // 320491072 绯绯 // 10139490 短短 // 116683 咬人猫 // 16539048 小仙若 // 10278125 香草猫饼 // 391073761 女团直拍 // $list = BilibiliUpVideos::all(); $list = []; $up = ["mid" => 391073761, "up_name" => "女团直拍"]; $up = ["mid" => 254624554, "up_name" => "女团能量站"]; $list[] = $up; foreach ($list as $item) { Log::info("schedule queryUpVideoList current up is {$item['up_name']}, started at: " . date("Y-m-d H:i:s")); $files = scandir($this->baseDir . "bilibili/" . $item['up_name']); $mediaId = $item['mid']; $videos = []; $pageNo = 1; $url = "https://api.bilibili.com/x/space/arc/search?mid={$mediaId}&ps=30&tid=0&keyword=&order=pubdate&jsonp=jsonp&pn="; // https://space.bilibili.com/475250/video for ($i = 1; $i < 50; $i++) { $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://api.bilibili.com/x/space/arc/search?mid={$mediaId}&ps=30&tid=0&keyword=&order=pubdate&jsonp=jsonp&pn={$i}", CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => array( "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", "Accept-Encoding: gzip, deflate, br", "Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6,ja;q=0.5", "Cache-Control: no-cache", "Connection: keep-alive", "Referer: https://www.bilibili.com", "Pragma: no-cache", "Sec-Fetch-Mode: navigate", "Sec-Fetch-Site: none", "Sec-Fetch-User: ?1", "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36", "cache-control: no-cache", ), )); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { // echo $response; $result = json_decode($response, true); $result = Arr::get($result["data"]["list"], "vlist", []); if (count($result) > 0) { foreach ($result as $vItem) { echo "av" . $vItem["aid"] . " "; // $videos[] = $vItem["aid"]; } } else { break; } } usleep(random_int(1000, 10000) * 1000); } // $item['videos'] = json_encode($videos); // $item['downloaded_videos'] = json_encode([]); // $item->save(); } } public function compareAndDownloadUpVideos($isAll = false) { $env = App::environment(); $list = BilibiliUpVideos::orderBy("created_at", "desc")->get(); foreach ($list as $item) { dump("当前 up名称是: " . $item["up_name"] . "\n"); if ($item["is_downloaded"] == 1) { continue; } if (!$this->checkDiskSpace()) { Log::info('磁盘空间不足'); exit; } Log::info("schedule compareAndDownloadUpVideos current up is {$item['up_name']}, started at: " . date("Y-m-d H:i:s")); if ($isAll) { $vItems = BilibiliVideos::where("up_mid", $item["mid"])->get(); } else { $vItems = BilibiliVideos::where('up_mid', $item["mid"]) ->where('created_at', '>=', date("Y-m-d H:i:s", strtotime("-1 week")))->get(); } $videoList = []; $videoPartsMap = []; if (count($vItems) > 0) { foreach ($vItems as $vItem) { if ($vItem["is_download"] == 1 && $vItem["download_status"] != 1) { // $videoList[] = "av" . $vItem["aid"]; if (!$this->repository->softLockUpdate(["id" => $vItem["id"]], $vItem["version"], ["download_status" => 1])) { Log::warning("soft Lock failed id : " . $vItem["id"]); continue; } $videoPartsMap = []; $videoPartsMap[$vItem["aid"]] = $vItem["total_parts"]; echo "当前 up名称是: " . $item["up_name"] . " 当前下载的视频 title: " . $vItem["title"] . " 当前下载的视频 aid 是:" . $vItem["aid"] . "\n"; Log::info("当前 up名称是: " . $item["up_name"] . " 当前下载的视频 title: " . $vItem["title"] . " 当前下载的视频 aid 是:" . $vItem["aid"]); if ($env == "local") { $result = false; if ($item['mid'] == 27174777) { $result = $this->partDownloadBSitePlaylist($videoPartsMap, "/Volumes/WD/tmp/bilibili/", "女团"); } else if ($item["mid"] == 391316322) { $result = $this->partDownloadBSitePlaylist($videoPartsMap, "/Volumes/WD/tmp/bilibili/", "娜娜"); } else if ($item["mid"] == 396501206) { $result = $this->partDownloadBSitePlaylist($videoPartsMap, "/Volumes/WD/tmp/bilibili/", "佳佳"); } else { $result = $this->partDownloadBSitePlaylist($videoPartsMap, $this->baseDir . "bilibili/", $item['up_name']); } if ($result) { if (!$this->repository->softLockUpdate( ["id" => $vItem["id"]], $vItem["version"] + 1, ["download_status" => 0, "is_downloaded" => 1, ])) { Log::warning("soft Lock failed id : " . $vItem["id"]); } } } else { $result = $this->partDownloadBSitePlaylist($videoPartsMap, $this->remoteDir . "bilibili/", $item["up_name"]); if ($result) { if (!$this->repository->softLockUpdate( ["id" => $vItem["id"]], $vItem["version"] + 1, ["download_status" => 0, "is_downloaded" => 1, ])) { Log::warning("soft Lock failed id : " . $vItem["id"]); } } } } } } } } public function compareAndDownloadCollectionVideos($isAll = false) { $env = App::environment(); $list = BilibiliCollections::all(); foreach ($list as $item) { dump("收藏夹名称是: " . $item["title"] . "\n"); if ($item["is_downloaded"] == 1) { continue; } if (!$this->checkDiskSpace()) { Log::info('磁盘空间不足'); exit; } Log::info("schedule compareAndDownloadCollectionVideos current collection is {$item['title']}, started at: " . date("Y-m-d H:i:s")); $videoList = []; $videoPartsMap = []; if ($isAll) { $vItems = BilibiliVideos::where("collection_mid", $item["media_id"])->get(); } else { $vItems = BilibiliVideos::where('collection_mid', $item["media_id"]) ->where('created_at', '>=', date("Y-m-d H:i:s", strtotime("-1 week")))->get(); } if (count($vItems) > 0) { foreach ($vItems as $vItem) { if ($vItem["is_download"] == 1 && $vItem["is_downloaded"] == 0 && $vItem["download_status"] == 0) { // $videoList[] = "av" . $vItem["aid"]; if (!$this->repository->softLockUpdate(["id" => $vItem["id"]], $vItem["version"], ["download_status" => 1])) { Log::warning("soft Lock failed id : " . $vItem["id"]); continue; } $videoPartsMap = []; $videoPartsMap[$vItem["aid"]] = $vItem["total_parts"]; echo "收藏夹名称是: " . $item["title"] . " 当前下载的视频 title: " . $vItem["title"] . " 当前下载的视频 aid 是:" . $vItem["aid"] . "\n"; Log::info("收藏夹名称是: " . $item["title"] . " 当前下载的视频 title: " . $vItem["title"] . " 当前下载的视频 aid 是:" . $vItem["aid"]); if ($env == "local") { $result = false; if ($item['title'] == "默认收藏夹") { dump("xxxxxxxxxxxx----------------"); $result = $this->partDownloadBSitePlaylist($videoPartsMap, "/Volumes/WD/tmp/", "bilibili"); } else if ($item['title'] == '少女时代') { $result = $this->partDownloadBSitePlaylist($videoPartsMap, "/Volumes/WD/tmp/bilibili/少女时代", ""); } else if ($item['title'] == 'aoa') { $result = $this->partDownloadBSitePlaylist($videoPartsMap, "/Volumes/WD/tmp/bilibili/aoa", ""); } else if ($item['title'] == 'blackpink') { $result = $this->partDownloadBSitePlaylist($videoPartsMap, "/Volumes/WD/tmp/bilibili/blackpink", ""); } else if ($item['title'] == 'wjsn') { $result = $this->partDownloadBSitePlaylist($videoPartsMap, "/Volumes/WD/tmp/bilibili/wjsn", ""); } else { $result = $this->partDownloadBSitePlaylist($videoPartsMap, $this->baseDir . "bilibili/", $item['title']); } if ($result) { if (!$this->repository->softLockUpdate( ["id" => $vItem["id"]], $vItem["version"] + 1, ["download_status" => 0, "is_downloaded" => 1, ])) { Log::warning("soft Lock failed id : " . $vItem["id"]); } } } else { $result = $this->partDownloadBSitePlaylist($videoPartsMap, $this->remoteDir . "bilibili", $item["title"]); if ($result) { if (!$this->repository->softLockUpdate( ["id" => $vItem["id"]], $vItem["version"] + 1, ["download_status" => 0, "is_downloaded" => 1, ])) { Log::warning("soft Lock failed id : " . $vItem["id"]); } } } } } } } } public function queryFavList() { // aoa 50076725 // default 50069625 // 美腿 156009025 // 允儿 154442125 // 少女时代 153944525 $invalidTitle = "已失效视频"; $pageNo = 1; for ($i = 1; $i < 65; $i++) { $curl = curl_init(); $url = "https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id=154442125&pn={$i}&ps=20&keyword=&order=mtime&type=0&tid=0&jsonp=jsonp"; curl_setopt_array($curl, array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => array( "Accept: application/json, text/plain, */*", "Accept-Encoding: gzip, deflate, br", "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6,ja;q=0.5", "Cache-Control: no-cache", "Connection: keep-alive", // "Cookie: buvid3=5566647C-DDE5-4AFF-8711-89C9DB2B7061110244infoc; LIVE_BUVID=AUTO2315591376644842; sid=kbyrjw72; stardustvideo=1; CURRENT_FNVAL=16; rpdid=|(J~|JluJmmk0J\'ullmuJ~~kJ; CURRENT_QUALITY=80; UM_distinctid=16b11bb4099eb-033fd8b69a435d-37647e03-13c680-16b11bb40bf97; fts=1562149769; im_notify_type_279025=0; _uuid=69A60E94-E8FE-54B8-DCCD-0F519F0DEF7480343infoc; DedeUserID=279025; DedeUserID__ckMd5=9a79e15294e6b8bb; SESSDATA=b114a39d%2C1573361994%2C2ed0a2a1; bili_jct=b35f8e9780e4a80dd07f316f781f179b; bp_t_offset_279025=315386152995357818", "Cookie: SESSDATA=64a15917%2C1578628130%2Ceb05cdc1", "Host: api.bilibili.com", "Origin: https://space.bilibili.com", "Postman-Token: c7f849ec-aaf9-4c71-851d-4ca061e725d0,f8f582bc-4872-4aa7-b209-b926364d4d1a", "Referer: https://space.bilibili.com/279025/favlist", "Sec-Fetch-Mode: cors", "Sec-Fetch-Site: same-site", "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36", "cache-control: no-cache", ), )); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { $responseArr = json_decode($response, true); if ($responseArr['code'] == 0) { $data = $responseArr['data']; $medias = $data['medias']; if (count($medias) > 0) { foreach ($medias as $item) { if ($item['title'] != $invalidTitle) { echo "av" . $item['id'] . " "; } } } } } usleep(random_int(1000, 10000) * 1000); } } public function getAoaFavList($id = 50076725) { $invalidTitle = "已失效视频"; $pageNo = 1; for ($i = 1; $i < 65; $i++) { $curl = curl_init(); $url = "https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id=50076725&pn={$i}&ps=20&keyword=&order=mtime&type=0&tid=0&jsonp=jsonp"; curl_setopt_array($curl, array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => array( "Accept: application/json, text/plain, */*", "Accept-Encoding: gzip, deflate, br", "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,zh-TW;q=0.6,ja;q=0.5", "Cache-Control: no-cache", "Connection: keep-alive", "Cookie: buvid3=5566647C-DDE5-4AFF-8711-89C9DB2B7061110244infoc; LIVE_BUVID=AUTO2315591376644842; sid=kbyrjw72; stardustvideo=1; CURRENT_FNVAL=16; rpdid=|(J~|JluJmmk0J'ullmuJ~~kJ; CURRENT_QUALITY=80; UM_distinctid=16b11bb4099eb-033fd8b69a435d-37647e03-13c680-16b11bb40bf97; fts=1562149769; im_notify_type_279025=0; _uuid=69A60E94-E8FE-54B8-DCCD-0F519F0DEF7480343infoc; DedeUserID=279025; DedeUserID__ckMd5=9a79e15294e6b8bb; SESSDATA=b114a39d%2C1573361994%2C2ed0a2a1; bili_jct=b35f8e9780e4a80dd07f316f781f179b; bp_t_offset_279025=317592473398470273", "Host: api.bilibili.com", "Origin: https://space.bilibili.com", "Postman-Token: c7f849ec-aaf9-4c71-851d-4ca061e725d0,f8f582bc-4872-4aa7-b209-b926364d4d1a", "Referer: https://space.bilibili.com/279025/favlist", "Sec-Fetch-Mode: cors", "Sec-Fetch-Site: same-site", "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36", "cache-control: no-cache", ), )); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { echo "cURL Error #:" . $err; } else { $responseArr = json_decode($response, true); if ($responseArr['code'] == 0) { $data = $responseArr['data']; $medias = $data['medias']; if (count($medias) > 0) { foreach ($medias as $item) { if ($item['title'] != $invalidTitle) { echo "av" . $item['id'] . " "; } } } } } usleep(random_int(1000, 10000) * 1000); } } public function queryCollectionList() { // $curl = curl_init(); // // curl_setopt_array($curl, array( // CURLOPT_URL => "https://api.bilibili.com/medialist/gateway/base/created?pn=1&ps=100&up_mid=279025&is_space=0&jsonp=jsonp", // CURLOPT_RETURNTRANSFER => true, // CURLOPT_ENCODING => "", // CURLOPT_MAXREDIRS => 10, // CURLOPT_TIMEOUT => 0, // CURLOPT_FOLLOWLOCATION => true, // CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, // CURLOPT_CUSTOMREQUEST => "GET", // CURLOPT_HTTPHEADER => array( // "Connection: keep-alive", // "Pragma: no-cache", // "Cache-Control: no-cache", // "Accept: application/json, text/plain, */*", // "Origin: https://space.bilibili.com", // "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36", // "Sec-Fetch-Site: same-site", // "Sec-Fetch-Mode: cors", // "Referer: https://space.bilibili.com/279025/favlist?spm_id_from=333.851.b_696e7465726e6174696f6e616c486561646572.15", // "Accept-Encoding: gzip, deflate, br", // "Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6,ja;q=0.5", // "Cookie: _uuid=D6E5438B-5A95-439F-7512-FC3509457A9A28409infoc; buvid3=5566647C-DDE5-4AFF-8711-89C9DB2B7061110244infoc; LIVE_BUVID=AUTO3415734420289108; UM_distinctid=16e62db8b9934b-0f76f63ae51bee-1c3c6a5a-13c680-16e62db8b9acaf; CURRENT_FNVAL=16; stardustvideo=1; rpdid=|(ku|l|lRYlJ0J'ul~JYuYY|u; finger=0539dad4; im_notify_type_279025=0; sid=llgc5h9q; DedeUserID=279025; DedeUserID__ckMd5=9a79e15294e6b8bb; bili_jct=07b8811aa5ca68020eb0c11e0e01c22f; laboratory=1-1; CURRENT_QUALITY=80; SESSDATA=64a15917%2C1578628130%2Ceb05cdc1; bp_t_offset_279025=336855788264916597; INTVER=1" // ), // )); // // $response = curl_exec($curl); $response = $this->requestCollectionNumberList($this->collectionNumberListUrl, 1); $res = json_decode($response, true); if ($res['code'] == 0) { $list = $res['data']['list']; foreach ($list as $item) { $collection = new BilibiliCollections(); $collection->title = $item["title"]; $collection->is_downloaded = 0; $collection->media_id = $item["id"]; $currentList = []; for ($pageNo = 1; $pageNo < 100; $pageNo++) { $listResponse = $this->requestCollectionList($this->collectionListUrl, $item['id'], $pageNo); dump("pageNo: " . $pageNo); dump($listResponse); $responseArr = json_decode($listResponse, true); if ($responseArr['code'] == 0) { $data = $responseArr["data"]; $medias = Arr::get($data, "medias", []); if (count($medias) > 0) { foreach ($medias as $media) { if ($media['title'] != $this->invalidTitle) { $currentList[] = $media["id"]; } } } else { break; } } } $collection->videos = json_encode($currentList); $collection->save(); } } // curl_close($curl); echo $response; } public function queryDBCollectionList() { $list = BilibiliCollections::where('is_downloaded', 0) ->orderBy('updated_at', 'asc') ->take(50) ->get(); // $list = array_slice($list->toArray(), 43, 100); // dump($list);exit; foreach ($list as $item) { Log::info("schedule queryDBCollectionList current collection is: " . $item['title'] . " started at :" . date("Y-m-d H:i:s")); $currentList = []; for ($pageNo = 1; $pageNo < 5; $pageNo++) { $listResponse = $this->requestCollectionList($this->collectionListUrl, $item['media_id'], $pageNo); dump("pageNo: " . $pageNo); dump($listResponse); $responseArr = json_decode($listResponse, true); if ($responseArr['code'] == 0) { $data = $responseArr["data"]; $medias = Arr::get($data, "medias", []); if (count($medias) > 0) { foreach ($medias as $media) { if ($media['title'] != $this->invalidTitle) { $bVideo = BilibiliVideos::firstOrCreate(["aid" => $media["id"]], [ "title" => $media["title"], "from_type" => 1, "from_collection_name" => $item['title'], "bv_id" => $media["bv_id"], "collection_mid" => $item["media_id"], "up_mid" => 0, ]); if ($bVideo->from_type != 1) { $bVideo->from_type = 3; $bVideo->from_collection_name = $item["title"]; } $bVideo->bv_id = $media["bv_id"]; $bVideo->collection_mid = $item["media_id"]; $bVideo->save(); $currentList[] = $media["id"]; } } } else { break; } } } dump(json_encode($currentList)); $item->videos = json_encode($currentList); $item->save(); } } public function queryForVideoParts() { $i = 0; $list = BilibiliVideos::where('is_downloaded', '0') ->orderBy('id', 'desc') ->simplePaginate(50, null, 'page', $i); // dump($list->items()[0]->aid); while ($list->isNotEmpty() && $i < 50) { foreach ($list->items() as $item) { // dump("current item", [$item->getAttributes()]); if ($item->is_download == 0) { // 不需要下载 continue; } $response = $this->requestVideoParts($item->aid); dump($response); $responseJson = json_decode($response, true); if ($responseJson["code"] !== 0) { Log::error("response is error, aid: " . $item->aid . " response: " . $response); if ($responseJson["code"] == -404 || $responseJson["code"] == "-404" || $responseJson["message"] == "啥都木有") { Log::error("response is error and save is_download = 0, aid: " . $item->aid . " response: " . $response); $item->is_download = 0; $item->save(); } continue; } $partList = Arr::get($responseJson, "data"); if (count($partList) > 0) { foreach ($partList as $part) { if ($item["from_type"] == 1) { if ($item["from_collection_name"] == "默认收藏夹") { $downloadPath = $this->baseDir . "bilibili"; } else { $downloadPath = $this->baseDir . "bilibili/" . $item["from_collection_name"]; } } else { $downloadPath = $this->baseDir . "bilibili/" . $item["from_up_name"]; } $pItem = BilibiliVideoParts::firstOrCreate([ "aid" => $item->aid, "page" => $part["page"], ], [ "title" => $item["title"], "part" => $part["part"], "duration" => $part["duration"], "to_download_path" => $downloadPath, ]); $pItem["title"] = $item["title"]; $pItem["to_download_path"] = $downloadPath; $pItem->save(); } $item->total_parts = count($partList); $item->save(); } try { usleep(random_int(10, 100) * 1000); } catch (Exception $e) { } } $i++; $list = BilibiliVideos::simplePaginate(50, null, 'page', $i); try { usleep(random_int(10, 1000) * 1000); } catch (Exception $e) { } } // while ($list->hasPages()) { // foreach ($list as $item) { // $item-> // } // $list = BilibiliVideos::simplePaginate() // } } /** * 检查是否已下载 */ public function checkVideoHasDownload() { $i = 1; $list = BilibiliVideos::simplePaginate(50, null, 'page', $i); $dirFiles = []; $dirFiles["/Volumes/WD/tmp/bilibili"] = scandir("/Volumes/WD/tmp/bilibili"); $dirFiles["/Volumes/WD/tmp/bilibili/aoa"] = scandir("/Volumes/WD/tmp/bilibili/aoa"); $dirFiles["/Volumes/WD/tmp/bilibili/女团"] = scandir("/Volumes/WD/tmp/bilibili/女团"); $dirFiles["/Volumes/WD/tmp/bilibili/少女时代"] = scandir("/Volumes/WD/tmp/bilibili/少女时代"); while ($list->isNotEmpty()) { foreach ($list->items() as $item) { // dump("current item", [$item->getAttributes()]); if ($item['is_download'] == 0) { continue; } $list = BilibiliVideoParts::where(['aid' => $item['aid']])->get(); if (count($list) > 0) { foreach ($list as $part) { // dump("here is parts", [$part->getAttributes()]); if (is_dir($part["to_download_path"])) { // dump("this is path ".$part["to_download_path"]); if (array_key_exists($part["to_download_path"], $dirFiles)) { $files = Arr::get($dirFiles, $part["to_download_path"]); } else { $files = scandir($part["to_download_path"]); $dirFiles[$part["to_download_path"]] = $files; } // dump($files); $itemCount = 0; $toRemove = []; foreach ($files as $file) { if ($file == "." || $file == "..") { continue; } else { // dump("current file: ". $file ." ".$part["title"]); $pos = strpos($file, $part["title"]); // dump("current compare result " . $pos); if ($pos !== false) { // dump($file); $itemCount++; if (strpos($file, $part["title"] . " P" . $part["page"]) !== false) { Log::info("file matched " . $file); $toRemove[] = $file; $part["is_downloaded"] = 1; $part->save(); } } } } $dirFiles[$part["to_download_path"]] = array_diff($files, $toRemove); if ($itemCount == $item["total_parts"]) { $item["is_downloaded"] = 1; $item->save(); } } } } // exit; } $i++; $list = BilibiliVideos::simplePaginate(50, null, 'page', $i); // exit; } } public function checkVideoHasDownloadV2() { $i = 1; $list = BilibiliVideos::simplePaginate(50, null, 'page', $i); $dirFiles = []; $dirFiles["/Volumes/WD/tmp/bilibili"] = scandir("/Volumes/WD/tmp/bilibili"); $dirFiles["/Volumes/WD/tmp/bilibili/aoa"] = scandir("/Volumes/WD/tmp/bilibili/aoa"); $dirFiles["/Volumes/WD/tmp/bilibili/女团"] = scandir("/Volumes/WD/tmp/bilibili/女团"); $dirFiles["/Volumes/WD/tmp/bilibili/少女时代"] = scandir("/Volumes/WD/tmp/bilibili/少女时代"); while ($list->isNotEmpty()) { foreach ($list->items() as $item) { dump("current item", [$item->getAttributes()]); if ($item['is_download'] == 0) { continue; } $list = BilibiliVideoParts::where(['aid' => $item['aid']])->get(); if (count($list) > 0) { foreach ($list as $part) { // dump("here is parts", [$part->getAttributes()]); if (is_dir($part["to_download_path"])) { // dump("this is path ".$part["to_download_path"]); if (array_key_exists($part["to_download_path"], $dirFiles)) { $files = Arr::get($dirFiles, $part["to_download_path"]); } else { $files = scandir($part["to_download_path"]); $dirFiles[$part["to_download_path"]] = $files; } // dump($files); $itemCount = 0; $toRemove = []; foreach ($files as $file) { if ($file == "." || $file == "..") { continue; } else { dump("current file: " . $file . " " . $part["title"]); $pos = strpos($file, $part["title"]); // dump("current compare result " . $pos); if ($pos !== false) { dump($file); $itemCount++; if (strpos($file, $part["title"] . " P" . $part["page"]) !== false) { Log::info("file matched " . $file); $toRemove[] = $file; $part["is_downloaded"] = 1; $part->save(); } } } } $dirFiles[$part["to_download_path"]] = array_diff($files, $toRemove); if ($itemCount == $item["total_parts"]) { $item["is_downloaded"] = 1; $item->save(); } } } } // exit; } $i++; $list = BilibiliVideos::simplePaginate(50, null, 'page', $i); // exit; } } public function requestVideoParts($aid) { return $this->request($this->videoPartsUrl . $aid); } public function requestCollectionList($url, $mediaId, $pn) { return $this->request($url . "&media_id=" . $mediaId . "&pn=" . $pn, true); } public function requestCollectionNumberList($url, $pn) { return $this->request($url . "&pn=" . $pn); } public function request($url, $userCookie = false) { $curl = curl_init(); $headerArray = array( "Connection: keep-alive", "Pragma: no-cache", "Cache-Control: no-cache", "Accept: application/json, text/plain, */*", "Origin: https://space.bilibili.com", "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36", "Sec-Fetch-Site: same-site", "Sec-Fetch-Mode: cors", "Referer: https://space.bilibili.com/279025/favlist?spm_id_from=333.851.b_696e7465726e6174696f6e616c486561646572.15", "Accept-Encoding: gzip, deflate, br", "Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,zh-TW;q=0.6,ja;q=0.5", // "Cookie: SESSDATA=64a15917%2C1578628130%2Ceb05cdc1" ); if ($userCookie) { $cookie = Redis::connection()->get("bilibili_cookie"); $headerArray[] = "Cookie: $cookie"; // $headerArray[] = "Cookie: SESSDATA=94247a4e%2C1651981649%2C1dba1%2Ab1;"; // $headerArray[] = "Cookie: _uuid=D6E5438B-5A95-439F-7512-FC3509457A9A28409infoc; buvid3=5566647C-DDE5-4AFF-8711-89C9DB2B7061110244infoc; LIVE_BUVID=AUTO3415734420289108; UM_distinctid=16e62db8b9934b-0f76f63ae51bee-1c3c6a5a-13c680-16e62db8b9acaf; CURRENT_FNVAL=16; stardustvideo=1; rpdid=|(ku|l|lRYlJ0J'ul~JYuYY|u; im_notify_type_279025=0; sid=llgc5h9q; laboratory=1-1; CURRENT_QUALITY=80; INTVER=1; DedeUserID=279025; DedeUserID__ckMd5=9a79e15294e6b8bb; SESSDATA=b169300a%2C1581262828%2C3654f611; bili_jct=597a5b9adb6170698e396fb053bc4aba; bp_t_offset_279025=343238964368145599"; } curl_setopt_array($curl, array( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 10, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => $headerArray, )); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); if ($err) { Log::error($err); return null; } return $response; } public function downloadBSitePlaylist($aidList, $dir = "/Volumes/intel660p/video/mv/mp4", $subDir) { dump("downloadBSitePlaylist : xxxxxxxxxxxxxxxxxxxxxxxxxxxx"); $dirExists = is_dir($dir); if ($dirExists) { $innerDir = $dir . "/" . $subDir; if (!is_dir($innerDir)) { mkdir($innerDir); } foreach ($aidList as $aid) { Log::info("current download command is : cd '{$innerDir}' && annie -r https://www.bilibili.com/video/av80815149 -p " . $aid); $downloadResult = shell_exec('cd "' . $innerDir . '" && annie -r https://www.bilibili.com/video/av80815149 -p ' . $aid); Log::info($downloadResult); Log::info("current download result: " . $downloadResult); try { usleep(random_int(1000, 10000) * 1000); } catch (Exception $e) { } } } } /** * 分 p 下载视频 * @param $aidMap * @param string $dir * @param $subDir */ public function partDownloadBSitePlaylist($aidMap, $dir = "/Volumes/intel660p/video/mv/mp4", $subDir) { $env = App::environment(); $cookie = Redis::connection()->get("bilibili_cookie"); $dirExists = is_dir($dir); dump($dirExists); echo "dir is $dir, and $dirExists"; if ($dirExists) { $innerDir = $dir . "/" . $subDir; dump($innerDir); if (!is_dir($innerDir)) { mkdir($innerDir); } if (!$this->checkDiskSpace($innerDir)) { Log::info('磁盘空间不足'); exit; } echo "当前视频的下载路径是: " . $innerDir . "\n"; Log::info("当前视频的下载路径是: " . $innerDir); foreach ($aidMap as $aid => $parts) { dump($aid); Log::info("current download command is : cd '{$innerDir}' && annie -r https://www.bilibili.com/video/av80815149 -p " . $aid); if ($env == "local") { $downloadResult = shell_exec('export http_proxy=http://127.0.0.1:1087; export https_proxy=http://127.0.0.1:1087; cd "' . $innerDir . '" && url="https://www.bilibili.com/video/av' . $aid . '?p=" for i in $(seq 1 ' . $parts . ') do annie -f 64 $url$i done && echo "ok"'); } else { // 修改单个获取信息,否则会把合集列表都拉过来 $formatArray = []; for ($i = 1; $i <= $parts; $i++) { $formatInfoShell = "lux -j -i -c \"{$cookie}\" https://www.bilibili.com/video/av{$aid}?p=$i"; $formatInfoShellResult = shell_exec($formatInfoShell); $formatInfoList = json_decode($formatInfoShellResult, true); if (!is_array($formatInfoList)) { Log::error("$aid format info error " . $formatInfoShellResult); break; } $formatArray[] = $formatInfoList[0]; usleep(500 * 1000); } foreach ($formatArray as $formatInfo) { $keys = array_keys($formatInfo["streams"]); $largeHev1FormatCode = -1; $largeFormatCode = -1; $largeFormatStr = ""; foreach ($keys as $key) { if (str_contains($key, "-")) { $formats = explode("-", $key); // 127-12, 后面的 12 代表 hev1 编码的 // 这边是想要获取到 hev1 编码的最高清晰度格式 if ($formats[1] == "12" && (int) $formats[0] > $largeHev1FormatCode) { $largeHev1FormatCode = (int) $formats[0]; } } else { if ((int) $key > $largeFormatCode) { $largeFormatCode = $key; $largeFormatStr = $key; } } } if ($largeHev1FormatCode == -1) { $formatArray[] = $largeFormatStr; } else { $formatArray[] = $largeHev1FormatCode . "-12"; } } $downloadShell = "cd $innerDir"; for ($i = 1; $i <= count($formatArray); $i++) { $downloadShell .= " && lux -f " . $formatArray[$i - 1] . " -c \"" . $cookie . "\" https://www.bilibili.com/video/av" . $aid . "?p=" . $i; } $downloadShell .= " && echo \"ok\""; $downloadResult = shell_exec($downloadShell); // $downloadResult = shell_exec('cd "' . $innerDir . '" && url="https://www.bilibili.com/video/av' . $aid . '?p=" //for i in $(seq 1 ' . $parts . ') //do //lux -c "'. $cookie.'" $url$i //done && echo "ok"'); // } Log::info($downloadResult); Log::info("$aid current download result: " . $downloadResult); $lastLine = explode("\n", $downloadResult)[count(explode("\n", $downloadResult)) - 2]; Log::info("lastLine is $lastLine"); try { usleep(random_int(1000, 10000) * 1000); } catch (Exception $e) { } if (trim($lastLine) == 'ok') { return true; } else { return false; } } } } public function deleteFileNotContainP() { $dir = "/Volumes/intel660p/video/mv/mp4"; $files = scandir($dir); foreach ($files as $file) { if ($file == "." || $file == "..") { continue; } if (preg_match("#P\d{1,2}#", $file)) { echo $file . "\n"; } else { echo "to delete file " . $file . "\n"; unlink($dir . "/" . $file); } } } public function compareAndDownloadNewVideos() { $list = BilibiliCollections::all(); foreach ($list as $item) { if ($item['is_downloaded'] == 1) { continue; } $undownloaded = array_diff($item['videos'], $item['downloaded_videos']); } dump($list); } public function commonRequest($url, $cookie, $media_id, $pageNo) { $client = new Client([ // Base URI is used with relative requests 'base_uri' => 'https://api.bilibili.com', // You can set any number of default request options. 'timeout' => 2.0, ]); $jar = new \GuzzleHttp\Cookie\CookieJar; $r = $client->request('GET', 'http://httpbin.org/cookies', [ 'cookies' => $jar, ]); } public function insertDBTest() { $aNo = 484525; for ($i = 0; $i < 5000000; $i++) { $tempANo = $aNo + $i; $sql = "insert into `bilibili_video_temps`( `aid`, `title`, `from_type`, `from_collection_name`, `from_up_name`, `is_download`, `is_downloaded`, `total_parts`, `created_at`, `updated_at`) VALUES ( " . $tempANo . ", '【钢琴】《鬼灭之刃》OP《红莲华》by LiSA', 2, '', '绯绯', 1, 1, 1, '2020-01-08 10:05:40', '2020-01-13 23:35:17');"; $result = DB::insert($sql); if ($i % 100 == 0) { print_r($result); } usleep(10); } } public function searchVideoFiles($filename) { $list = BilibiliVideos::where("title", "like", "%" . trim($filename) . "%")->get(); dump($list); } public function checkDiskSpace($dir = "/Volumes/Crucial X6/Video/bilibili/") { if (disk_free_space($dir) > 5 * 1024 * 1024 * 1024) { return true; } return false; } public function downloadDynamics() { $env = App::environment(); $list = BilibiliUpVideos::orderBy("id", "desc")->offset(0)->limit(150)->get(); // ->where("id", ">=", "0") foreach ($list as $item) { sleep(rand(1, 15)); $mid = $item["mid"]; $offset = null; $response = null; $skipFlag = false; $index = 0; do { $index++; if ($skipFlag) { break; } sleep(rand(1, 15)); echo "=============== current up is {$item["up_name"]} ==================\n"; $doi = 0; do { $doi++; try { $jsonResponse = $this->dynamicsRequest($mid, $offset); break; } catch (Exception $e) { Log::error($e->getMessage()); } } while ($doi < 10); echo $jsonResponse; $response = json_decode($jsonResponse, true); if (array_key_exists("code", $response) && $response["code"] == '0' && array_key_exists("data", $response) && array_key_exists("items", $response["data"])) { $dynamics = $response["data"]["items"]; $skipFlag = false; foreach ($dynamics as $dynamic) { if ($dynamic["type"] == "DYNAMIC_TYPE_DRAW") { if (array_key_exists("modules", $dynamic) && array_key_exists("module_dynamic", $dynamic["modules"]) && array_key_exists("major", $dynamic["modules"]["module_dynamic"]) && array_key_exists("draw", $dynamic["modules"]["module_dynamic"]["major"]) && array_key_exists("items", $dynamic["modules"]["module_dynamic"]["major"]["draw"]) ) { $imageItems = $dynamic["modules"]["module_dynamic"]["major"]["draw"]["items"]; foreach ($imageItems as $imageItem) { $imageUrl = $imageItem["src"]; $this->downloadImage($imageUrl, "/Volumes/T7/Image/bili", $item["up_name"]); } } } else if ($dynamic["type"] == "DYNAMIC_TYPE_AV") { if (array_key_exists("modules", $dynamic) && array_key_exists("module_dynamic", $dynamic["modules"]) && array_key_exists("major", $dynamic["modules"]["module_dynamic"]) && array_key_exists("archive", $dynamic["modules"]["module_dynamic"]["major"]) && array_key_exists("bvid", $dynamic["modules"]["module_dynamic"]["major"]["archive"]) && array_key_exists("title", $dynamic["modules"]["module_dynamic"]["major"]["archive"]) ) { $exists = BilibiliVideos::where("aid", "=", $dynamic["modules"]["module_dynamic"]["major"]["archive"]["aid"])->first(); if ($exists !== null) { Log::info("current aid exist skip ================================="); $skipFlag = true; // break 2; } $bVideo = BilibiliVideos::firstOrCreate(["aid" => $dynamic["modules"]["module_dynamic"]["major"]["archive"]["aid"]], [ "title" => $dynamic["modules"]["module_dynamic"]["major"]["archive"]["title"], "from_type" => 2, "from_up_name" => $item["up_name"], "bv_id" => $dynamic["modules"]["module_dynamic"]["major"]["archive"]["bvid"], "up_mid" => $mid, "collection_mid" => 0, ]); if ($bVideo->from_type != 2) { $bVideo->from_type = 3; } $bVideo->bv_id = $dynamic["modules"]["module_dynamic"]["major"]["archive"]["bvid"]; $bVideo->up_mid = $mid; $bVideo->from_up_name = $item["up_name"]; $bVideo->save(); } } } } else { echo "====================== data is not normal ======================\n"; } if (array_key_exists("data", $response) && array_key_exists("offset", $response["data"])) { $offset = $response["data"]["offset"]; echo "{$item["up_name"]} offset: $offset \n"; } usleep(random_int(10, 100) * 100); } while ($response != null && array_key_exists("data", $response) && array_key_exists("has_more", $response["data"]) && $response["data"]["has_more"]); } } public function dynamicsRequest($mid, $offset) { $client = new Client(); // $headers = [ // 'accept' => '*/*', // 'accept-language' => 'zh-CN,zh;q=0.9', // 'cache-control' => 'no-cache', // 'cookie' => 'buvid3=67245DCB-26E6-BFE8-A096-2DCD816F484E66359infoc; b_nut=1711166466; b_lsid=910710766F_18E69782A5E; _uuid=2C7BEEC1-10A8D-DE75-C9DF-E88C755982EE66658infoc; buvid4=72E32FA0-3DA0-B59A-28D0-19ED46EE5F2666682-024032304-9hlK%2FyFTfkthMYAU943pxw%3D%3D; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTE0MjU2NjYsImlhdCI6MTcxMTE2NjQwNiwicGx0IjotMX0.F2zbZtMifzoytWVX--7GF9ScxMJMmzHRWCcJjsxR1n4; bili_ticket_expires=1711425606; buvid_fp=7844041d2a1a51c5f6efcc4061de1838', // 'origin' => 'https://space.bilibili.com', // 'pragma' => 'no-cache', // 'referer' => 'https://space.bilibili.com/496504596/dynamic', // 'sec-ch-ua' => '"Google Chrome";v="123", "Not:A-Brand";v="8", "Chromium";v="123"', // 'sec-ch-ua-mobile' => '?0', // 'sec-ch-ua-platform' => '"macOS"', // 'sec-fetch-dest' => 'empty', // 'sec-fetch-mode' => 'cors', // 'sec-fetch-site' => 'same-site', // 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36' // ]; $headers = [ 'accept' => '*/*', 'accept-language' => 'zh-CN,zh;q=0.9', 'cache-control' => 'no-cache', 'cookie' => 'buvid3=BB2A4D5B-11A0-EC98-E67C-F2ECED51252D86432infoc; b_nut=1734395686; b_lsid=BE1058F9B_193D20A03B6; _uuid=710A46510F-EF510-82BC-ADA1-109F10959EFFA691964infoc; buvid_fp=6e25adce2c1a5f6f37bc796e0e5d0ac2; enable_web_push=DISABLE; home_feed_column=5; browser_resolution=1512-857; buvid4=464EFD3C-221D-0F82-BC3B-C2E217DDFBE194492-024121700-IeDz9F592rGhrGUI/Qk4mw%3D%3D; CURRENT_FNVAL=2000; sid=fs8i6afm; bili_ticket=eyJhbGciOiJIUzI1NiIsImtpZCI6InMwMyIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzQ2NTQ5MDYsImlhdCI6MTczNDM5NTY0NiwicGx0IjotMX0.so25MAGIDzGSfgt-5hSDFgweUEE63ciiykyMhsYqsMM; bili_ticket_expires=1734654846', 'origin' => 'https://space.bilibili.com', 'pragma' => 'no-cache', 'priority' => 'u=1, i', 'referer' => 'https://space.bilibili.com/418125910/dynamic', 'sec-ch-ua' => '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"', 'sec-ch-ua-mobile' => '?0', 'sec-ch-ua-platform' => '"macOS"', 'sec-fetch-dest' => 'empty', 'sec-fetch-mode' => 'cors', 'sec-fetch-site' => 'same-site', 'user-agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' ]; if ($offset != null) { $url = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset={$offset}&host_mid={$mid}&timezone_offset=-480&features=itemOpusStyle"; } else { $url = "https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset=&host_mid={$mid}&timezone_offset=-480&features=itemOpusStyle"; } $request = new Request('GET', $url, $headers); $res = $client->sendAsync($request, ['connect_timeout' => 100, 'debug' => true])->wait(); return $res->getBody(); } public function downloadImage($imageUrl, $path, $upName) { $filePathInfo = pathinfo($imageUrl); $filename = $filePathInfo['basename']; $request = new Request('GET', $imageUrl); try { $res = $this->client->sendAsync($request)->wait(); } catch (\Exception $e) { Log::error("$upName, $imageUrl, is error " . $e->getMessage()); return; } $fileLocalName = $path . DIRECTORY_SEPARATOR . $upName . "_" . $filename; if (is_file($fileLocalName) && filesize($fileLocalName) > 10000) { echo $fileLocalName . " exists \n"; } else { file_put_contents($path . DIRECTORY_SEPARATOR . $upName . "_" . $filename, $res->getBody()); } } public function getMixinKey($orig) { // '对 imgKey 和 subKey 进行字符顺序打乱编码' return substr(implode('', array_map(function ($i) use ($orig) { return $orig[$i]; }, $this->mixinKeyEncTab)), 0, 32); } public function encWbi($params, $img_key, $sub_key) { // '为请求参数进行 wbi 签名' $mixin_key = $this->getMixinKey($img_key . $sub_key); $curr_time = round(time()); $params['wts'] = $curr_time; // 添加 wts 字段 ksort($params); // 按照 key 重排参数 $params = array_map(function ($v) { return preg_replace("#[!'()*/]#", '', $v); // 过滤 value 中的 "!'()*" 字符 }, $params); $query = http_build_query($params); // 序列化参数 $query = str_replace("&dm_img_str", "&dm_img_list=%5B%5D&dm_img_str", $query); // echo $query;exit; $wbi_sign = md5($query . $mixin_key); // 计算 w_rid $params['w_rid'] = $wbi_sign; return $params; } public function encWbiString($paramString, $img_key, $sub_key) { $mixin_key = $this->getMixinKey($img_key . $sub_key); $curr_time = round(time()); $wts = $curr_time; // 添加 wts 字段 // echo "before $paramString \n"; // preg_replace("#[!'()*/]#", '', $paramString); // echo "after $paramString \n"; $wbi_sign = md5($paramString . "&wts=" . $wts . $mixin_key); // 计算 w_rid // echo "\n wbi sign is $wbi_sign \n";exit; $params['w_rid'] = $wbi_sign; $params["new"] = $paramString . "&w_rid=" . $wbi_sign . "&wts=" . $wts; return $params; } public function getWbiKeys() { $img_key = Redis::connection()->get("img_key"); $sub_key = Redis::connection()->get("sub_key"); if ($img_key != null && $sub_key != null) { return [$img_key, $sub_key]; } // '获取最新的 img_key 和 sub_key' $resp = file_get_contents('https://api.bilibili.com/x/web-interface/nav'); $json_content = json_decode($resp, true); $img_url = $json_content['data']['wbi_img']['img_url']; $sub_url = $json_content['data']['wbi_img']['sub_url']; $img_key = substr($img_url, strrpos($img_url, '/') + 1, strrpos($img_url, '.') - strrpos($img_url, '/') - 1); $sub_key = substr($sub_url, strrpos($sub_url, '/') + 1, strrpos($sub_url, '.') - strrpos($sub_url, '/') - 1); Redis::connection()->setex("img_key", strtotime('23:59:59') - time(), $img_key); Redis::connection()->setex("sub_key", strtotime('23:59:59') - time(), $sub_key); return [$img_key, $sub_key]; } public function build_params($params) { list($img_key, $sub_key) = $this->getWbiKeys(); // dump($img_key); // dump($sub_key); if (gettype($params) == "string") { $query = $this->encWbiString($params, $img_key, $sub_key); } else { $signed_params = $this->encWbi( $params, $img_key, $sub_key ); // dump($signed_params);exit; $query = http_build_query($signed_params); } // print_r($signed_params); return $query; } public function randFloat($min = 0, $max = 1) { return $min + mt_rand() / mt_getrandmax() * ($max - $min); } public function GetRandStr($length) { //字符组合 $str = 'ABCDEFGHIJK'; $len = strlen($str) - 1; $randstr = ''; for ($i = 0; $i < $length; $i++) { $num = mt_rand(0, $len); $randstr .= $str[$num]; } return $randstr; } public function getWebId() { $content = file_get_contents("https://space.bilibili.com/16720403/video"); // echo $content; $start = ''; $pos1 = strpos($content, $start, 0); $pos2 = strpos($content, $end, $pos1); // echo "\n" . $pos1; // echo "\n" . $pos2; $encodeStr = substr($content, $pos1 + strlen($start), $pos2 - $pos1 - strlen($start)); // echo "\n" . urldecode($encodeStr); return json_decode(urldecode($encodeStr), true)["access_id"]; } public function queryBiliUpListNew($mediaId = 320491072, $startPos = 0, $limit = 20) { Log::info("schedule queryUpVideoList inner started at: " . date("Y-m-d H:i:s")); // 475250 kyokyo // 3489535 熊小颖 // 320491072 绯绯 // 10139490 短短 // 116683 咬人猫 // 16539048 小仙若 // 10278125 香草猫饼 // 391073761 女团直拍 // 267781236 韩国女团饭拍直拍 // 23400436 小雪_juvia $list = BilibiliUpVideos::where("id", "<=", "200") ->orderBy('id', 'desc') ->offset($startPos) ->limit($limit) ->get(); // $list = $list->slice(5); $url = "https://app.bilibili.com/x/v2/space/archive/cursor?order=pubdate&vmid="; foreach ($list as $key => $item) { $aid = null; $i = 0; do { $i++; Log::info("schedule queryUpVideoList current up is {$item['up_name']}, started at: " . date("Y-m-d H:i:s")); echo $item["mid"] . " " . $item["up_name"]; if ($aid != null) { echo " has next \n"; $content = file_get_contents($url . $item["mid"] . "&aid=" . $aid); } else{ echo " start \n"; $content = file_get_contents($url . $item["mid"]); } $jsonContent = json_decode($content, true); if (array_key_exists("data", $jsonContent) && array_key_exists("item", $jsonContent["data"]) && $jsonContent["data"]["item"] != null && count($jsonContent["data"]["item"]) > 0) { $aid = null; foreach ($jsonContent["data"]["item"] as $vItem) { $avid = substr($vItem["three_point"][1]["share_path"], strpos($vItem["three_point"][1]["share_path"], "=") + 1); // echo $avid;exit; if(BilibiliVideos::where(["bv_id" => $vItem["bvid"]])->exists() && $i > 2) { echo "bvid " . $vItem["bvid"] . " " . $vItem["title"] . " exist skip to next\n"; break 2; } $bVideo = BilibiliVideos::firstOrCreate(["bv_id" => $vItem["bvid"]], [ "title" => $vItem["title"], "from_type" => 2, "from_up_name" => $item["up_name"], "bv_id" => $vItem["bvid"], "aid" => $avid, "up_mid" => $item["mid"], "collection_mid" => 0, ]); if ($bVideo->from_type != 2) { $bVideo->from_type = 3; } $bVideo->bv_id = $vItem["bvid"]; $bVideo->up_mid = $item["mid"]; $bVideo->from_up_name = $item["up_name"]; $bVideo->save(); $aid = $vItem["param"]; } } usleep(random_int(1000, 10000) * 1000); } while ($jsonContent["data"]["has_next"] && $aid != null); // exit; } } }