直接上代碼
#!/usr/bin/env php
<?php
//php下載m3u8文件
$url = $argv['1'];
if (!file_exists('./tmp/')) {
if (!mkdir('./tmp/')) {
die('請(qǐng)手動(dòng)在當(dāng)前目錄創(chuàng)建tmp目錄');
}
}
$indexPage = file_get_contents($url);
$tsArr = [];
$flag = 0;
foreach (explode("\n", $indexPage) as $v) {
if ($flag == 1) {
$tsArr[] = $v;
$flag = 0;
}
if (stripos($v, '#EXTINF:') === 0) {
$flag = 1;
}
}
go(function () use ($tsArr, $url) {
$chan = new chan(100); //最大并發(fā)數(shù)
foreach ($tsArr as $key => $value) {
if (file_exists('./tmp/' . md5($url) . "-" . $key . '.ts')) {
continue;
}
$chan->push('xx');
go(function () use ($key, $value, $chan, $url) {
echo "\nAdd task:" . $key;
while (1) {
$rs = co_curl($value);
if (strlen($rs) > 0) {
file_put_contents('./tmp/' . md5($url) . "-" . $key . '.ts', $rs);
break;
}
}
echo "\nTask ok:" . $key;
$chan->pop();
});
}
//確保所有下載已經(jīng)完成
for ($i = 0; $i < 100; $i++) {
$chan->push('over');
}
//合并文件
foreach ($tsArr as $key => $value) {
file_put_contents('out.mp4', file_get_contents('./tmp/' . md5($url) . "-" . $key . '.ts'), FILE_APPEND);
unlink('./tmp/' . md5($url) . "-" . $key . '.ts');
}
echo "\n 下載完成,轉(zhuǎn)換成功 (out.mp4)";
});
function co_curl($url, $cookies = '', $data = array(), $userHeaders = array(), $retJson = 0)
{
while (1) {
$urlInfo = parse_url($url);
$domain = $urlInfo['host'];
if ($urlInfo['scheme'] == 'https') {
$port = 443;
$ssl = true;
} else {
$port = isset($urlInfo['port']) ? $urlInfo['port'] : 80;
$ssl = false;
}
$filename = $urlInfo['path'];
$filename .= isset($urlInfo['query']) ? '?' . $urlInfo['query'] : '';
$cli = new Swoole\Coroutine\Http\Client($domain, $port, $ssl);
$headers = [
'Host' => $domain,
"User-Agent" => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36',
'Accept' => 'text/html,application/xhtml+xml,application/xml',
'Accept-Encoding' => 'gzip',
];
if ($userHeaders) {
$headers = array_merge($headers, $userHeaders);
$headers = $userHeaders;
}
if ($cookies) {
$headers['Cookie'] = $cookies;
}
$cli->setHeaders($headers);
$cli->set(['timeout' => 60]);
if ($data) {
if ($data == 'post') {
$data = '';
}
$cli->post($filename, $data);
} else {
$cli->get($filename);
}
$body = $cli->body;
$cli->close();
if ($cli->statusCode < 1 || ($retJson && empty(json_decode($body, true)))) {
// echo "\n status code:" . $cli->statusCode;
// echo "\n body: ".$body;
// echo "\n retry...";
} else {
return $body;
}
}
}
使用方法
php index.php https://doubanzyv1.tyswmp.com/2018/07/30/LSn7hSBfY0LxpKX2/playlist.m3u8
輸出文件路徑
當(dāng)前目錄的out.mp4