当前位置:   article > 正文

PHP下载m3u8,合并视频_php 合并m3u8视频文件

php 合并m3u8视频文件

主要使用CURL获取请求,代码:

将代码保存为m3u8-download.php,然后执行:

如果下载速度比较慢,要把Curl的超时时间设置长一点,防止出现超时丢数据。

c:\>php m3u8-download.php -u http://xxx/xxx.m3u8 -o 要保存为的文件名
  1. <?php
  2. if (!function_exists('curl_init')) {
  3. println('need Curl module. please install it!', true);
  4. }
  5. $options = getopt('u:o:b:rh');
  6. if (isset($options['h'])) {
  7. $help = <<<EOT
  8. -h 帮助
  9. -u m3u8的URL
  10. -o 输出文件,默认:out.mp4
  11. -b 每批网络请求的数量,默认:10
  12. -r 保留下载的临时文件
  13. EOT;
  14. }
  15. if (!isset($options['u'])) {
  16. println('no .m3u8 file url', true);
  17. }
  18. $u = $options['u'];
  19. $o = isset($options['o']) ? $options['o'] : 'out.mp4';
  20. $b = isset($options['b']) ? $options['b'] : 10;
  21. $r = isset($options['r']);
  22. $url_blocks = array();
  23. $dir = dirname(__FILE__) . '/tmp/' . md5($u);
  24. $ts_dir = $dir . '/ts';
  25. $url_file = $dir . '/url.txt';
  26. $response_file = $dir . '/response.txt';
  27. $list_file = $dir . '/url_list.txt';
  28. $pos_file = $dir . '/pos.txt';
  29. $block_index = $index = 0;
  30. if (file_exists($list_file)) {
  31. println('load index file...');
  32. $url_blocks = require($list_file);
  33. if (is_file($pos_file)) {
  34. $pos = file_get_contents($pos_file);
  35. list($block_index, $index) = explode(':', $pos);
  36. }
  37. } else {
  38. println('read index file...');
  39. if (!file_exists($ts_dir)) {
  40. mkdir($ts_dir, 0775, true);
  41. }
  42. file_put_contents($url_file, $u);
  43. $response = $header = $body = '';
  44. if (httpGet($u, $response, $header, $body)) {
  45. file_put_contents($response_file, $response);
  46. $files = trim(preg_replace('/^#.+[\r\n]+/m', '', $body));
  47. $urls = preg_split("/[\r\n]+/", $files);
  48. $block = array();
  49. foreach ($urls as $key => $item) {
  50. $block[] = fixUrl($u, $item);
  51. if (($key + 1) % $b == 0) {
  52. $url_blocks[] = $block;
  53. $block = array();
  54. }
  55. }
  56. $url_blocks[] = $block;
  57. file_put_contents($list_file, '<?php return ' . var_export($url_blocks, true) . ';');
  58. }
  59. }
  60. //print_r($url_blocks);
  61. //exit;
  62. if ($url_blocks) {
  63. println('download, please wait...');
  64. $max = count($url_blocks);
  65. for ($i = $block_index; $i < $max; $i++) {
  66. $contents = httpMultiGet($url_blocks[$i]);
  67. if ($contents) {
  68. foreach ($contents as $content) {
  69. file_put_contents($ts_dir . '/' . $index . '.ts', $content);
  70. file_put_contents($pos_file, $i . ':' . $index);
  71. $index++;
  72. }
  73. } else {
  74. $i--; // 有请求失败的,重试
  75. }
  76. progress($max, $i + 1);
  77. }
  78. println('merge file...');
  79. $fp = fopen($o, 'wb');
  80. if ($fp) {
  81. for ($i = 0; $i < $index; $i++) {
  82. $content = file_get_contents($ts_dir . '/' . $i . '.ts');
  83. fwrite($fp, $content);
  84. progress($index, $i + 1);
  85. }
  86. fclose($fp);
  87. }
  88. if (!$r) {
  89. println('clean tmp file...');
  90. for ($i = 0; $i < $index; $i++) {
  91. unlink($ts_dir . '/' . $i . '.ts');
  92. }
  93. unlink($pos_file);
  94. unlink($response_file);
  95. }
  96. println('done.', true);
  97. } else {
  98. println('get index file fail.', true);
  99. }
  100. // ===============================
  101. // functions
  102. // ===============================
  103. function println($string, $exit = false)
  104. {
  105. echo $string . "\r\n";
  106. if ($exit) {
  107. exit();
  108. }
  109. }
  110. function progress($max, $current, $message = '')
  111. {
  112. $p = 0;
  113. if ($current) {
  114. $p = round($current / $max * 100, 2);
  115. }
  116. printf("progress: [%-50s] %d%% {$message}\r", str_repeat('#', ceil($p / 2)), $p);
  117. if ($current == $max) {
  118. echo "\n";
  119. }
  120. }
  121. function fixUrl($current, $target)
  122. {
  123. $target = str_replace('\\', '/', $target);
  124. if (false === strpos($target, '://')) {
  125. $current = str_replace('\\', '/', $current);
  126. $url_parts = parse_url($current);
  127. $host = $url_parts['scheme'] . '://' . $url_parts['host'] . (isset($url_parts['port']) ? ':' . $url_parts['port'] : '') . '/';
  128. if (0 === strpos($target, '//')) {
  129. return $url_parts['scheme'] . ':' . $target;
  130. } else {
  131. if (0 === strpos($target, '/')) {
  132. $url_path = '';
  133. } else {
  134. if (isset($url_parts['path'])) {
  135. $url_path = $url_parts['path'];
  136. if (false !== strpos($url_path, '.')) {
  137. $url_path = (false !== ($pos = strrpos($url_path, '/'))) ? substr($url_path, 0, $pos + 1) : $url_path;
  138. }
  139. }
  140. }
  141. $parts = explode('/', $url_path . $target);
  142. $arcv = array();
  143. foreach ($parts as $value) {
  144. if ($value !== '' && $value != '.') {
  145. if ($value == '..') {
  146. array_pop($arcv);
  147. } else {
  148. $arcv[] = $value;
  149. }
  150. }
  151. }
  152. return $host . implode('/', $arcv);
  153. }
  154. }
  155. return $target;
  156. }
  157. function mkCurlHandler($url)
  158. {
  159. $curl = curl_init();
  160. curl_setopt($curl, CURLOPT_HEADER, true); //表示需要response header
  161. curl_setopt($curl, CURLOPT_NOBODY, false);
  162. curl_setopt($curl, CURLOPT_AUTOREFERER, true);
  163. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  164. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  165. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
  166. curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64; rv:71.0) Gecko/20100101 Firefox/71.0');
  167. curl_setopt($curl, CURLOPT_TIMEOUT, 120); // 时间长一些防止超时
  168. curl_setopt($curl, CURLOPT_REFERER, $url);
  169. curl_setopt($curl, CURLOPT_URL, $url);
  170. return $curl;
  171. }
  172. function httpGet($url, &$response, &$response_header, &$response_body)
  173. {
  174. $curl = mkCurlHandler($url);
  175. $response = curl_exec($curl);
  176. $info = curl_getinfo($curl);
  177. $status = false;
  178. if ($info['http_code'] == 200) {
  179. $parts = explode("\r\n\r\n", $response, 2);
  180. if (count($parts) > 1) {
  181. list($response_header, $response_body) = $parts;
  182. $status = true;
  183. }
  184. }
  185. curl_close($curl);
  186. return $status;
  187. }
  188. function httpMultiGet($urls)
  189. {
  190. $bodys = array();
  191. $handlers = array();
  192. $mh = curl_multi_init();
  193. foreach ($urls as $i => $url) {
  194. $handler = mkCurlHandler($url);
  195. curl_multi_add_handle($mh, $handler);
  196. $handlers[$i] = $handler;
  197. }
  198. $active = null;
  199. do {
  200. $mrc = curl_multi_exec($mh, $active);
  201. } while ($mrc == CURLM_CALL_MULTI_PERFORM);
  202. while ($active && $mrc == CURLM_OK) { //直到出错或者全部读写完毕
  203. if (curl_multi_select($mh) != -1) { // 防止CPU过高
  204. do {
  205. $mrc = curl_multi_exec($mh, $active);
  206. } while ($mrc == CURLM_CALL_MULTI_PERFORM);
  207. }
  208. }
  209. foreach ($handlers as $i => $handler) {
  210. //获取当前解析的cURL的相关传输信息
  211. //$info = curl_multi_info_read($mh);
  212. $heards = curl_getinfo($handler);
  213. $response = curl_multi_getcontent($handler);
  214. if ($heards['http_code'] == 200) {
  215. $parts = explode("\r\n\r\n", $response, 2);
  216. if (count($parts) > 1) {
  217. list($response_header, $response_body) = $parts;
  218. $bodys[] = $response_body;
  219. if ($response_body == '') {
  220. return array();
  221. }
  222. } else {
  223. return array();
  224. }
  225. }
  226. curl_multi_remove_handle($mh, $handler);
  227. curl_close($handler);
  228. }
  229. curl_multi_close($mh);
  230. return $bodys;
  231. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/246092?site
推荐阅读
相关标签
  

闽ICP备14008679号