zoukankan      html  css  js  c++  java
  • 下载m3u8视频

    使用ffmpeg直接下载

    ffmpeg -i "http://host/folder/file.m3u8" -bsf:a aac_adtstoasc -c copy -crf 50 file.mp4
    

    手动解析下载

    有些m3u8可能不一样

    import 'dart:io';
    
    import 'package:process_run/shell.dart';
    import 'package:ajanuw_http/ajanuw_http.dart';
    import 'package:path/path.dart' as path;
    
    var urlBase = 'https://www.gentaji.com/20200205/2J8Ij9tS/index.m3u8';
    
    var __filename = Platform.script.path.replaceFirst('/', '');
    var __dirname = path.dirname(__filename);
    
    var download_path = path.normalize(path.joinAll([__dirname, '..', 'download']));
    
    void download(String url) async {
      // 获取第一层M3U8文件内容
      var all_content = (await url.get()).body;
      if (!all_content.contains('#EXTM3U')) {
        throw ('非M3U8的链接');
      }
    
      if (all_content.contains('EXT-X-STREAM-INF')) {
        var file_line = all_content.split('
    ');
    
        for (var line in file_line) {
          if (line.contains('.m3u8')) {
            url = Uri.parse(url).replace(path: line).toString(); // 拼出第二层m3u8的URL
            all_content = (await url.get()).body;
          }
        }
      }
    
      var file_line = all_content.split('
    ');
      var unknow = true;
    
      var total = file_line.length;
      for (var i = 0; i < total; i++) {
        var line = file_line[i];
        if (line.contains('#EXT-X-KEY')) {
          print('找解密Key');
        }
    
        if (line.contains('EXTINF')) {
          unknow = false;
          var pd_url = file_line[i + 1]; // https://gentaji.com/20200205/2J8Ij9tS/1200kb/hls/0o8RU9r8.ts
          if (pd_url != null && Uri.parse(pd_url).scheme.isNotEmpty) {
            var c_fule_name = '$i-${path.basename(pd_url)}'; // 0o8RU9r8.ts
            var f = File(path.join(download_path, c_fule_name));
            if (!await f.exists()) {
              print('index: $i total: $total');
              var res = await pd_url.get();
              await f.writeAsBytes(res.bodyBytes);
            } else {
              print(f.path + ' 文件已经存在!');
            }
          } else {
            print('下载连接错误: ' + pd_url);
          }
        }
      }
    
      if (unknow) {
        throw '未找到对应的下载链接';
      } else {
        print('下载完成');
      }
    
      merge_file();
    }
    
    void merge_file() async {
      // sh: cd <download_path>
      // 改变工作目录
      Directory.current = Directory(download_path);
      var shell = Shell();
    
      // 将按顺序把每个文件内容push到new.tmp
      // 可能会合并错误
      await shell.run('''copy /b * new.m3u8''');
      // await shell.run('''del /Q *.ts''');
      // await shell.run('''del /Q *.mp4''');
      // await File('new.m3u8').rename('new.mp4');
    
      // 使用ffmpeg工具将合并的ts文件,解码为mp4文件,上面通过直接改变后缀名的方法貌似不行
      await shell.run('''ffmpeg -i new.m3u8 -bsf:a aac_adtstoasc -c copy -crf 50 video.mp4''');
    
      // 和上面的一样
      // await shell.run('''ffmpeg -i new.m3u8 -b:v 0 -crf 25 -f mp4 -vcodec libx264 -pix_fmt yuv420p video.mp4''');
    }
    
    void main() async {
      var dowloadDir = Directory(download_path);
      if (!await dowloadDir.exists()) {
        await dowloadDir.create();
      }
    
      download(urlBase);
    }
    
  • 相关阅读:
    7个技巧,帮你完美搞定网页首图设计(必看)
    听说你想跳槽?ARM和PowerPC分析,你知道吗?(速进)
    C语言必学7大步骤!(必看)
    单片机电机必不可少的30条常识!你知道吗?(欢迎大家进行补充)
    单片机外围电路设计攻略(终结版)! 不看哭一年!
    3天”速成“嵌入式之后,我明白了六件事!!!
    前端就不需要掌握算法与数据结构?
    嵌入式软件必学知识总结!
    字节跳动2017客户端工程师实习生笔试题-第四题
    并查集
  • 原文地址:https://www.cnblogs.com/ajanuw/p/12564036.html
Copyright © 2011-2022 走看看