2018年8月31日 更新,经过了一段时间的使用,我决定把这个下载类再升级一下。升级为一个工具类。我贴在了另一篇帖子中。
M3U8下载,直播源下载,FLASH下载(四)-直播源下载-工具类


前言

  在工作或者生活中,我们往往会在网页中碰见一些不错的视频,想下载下来存到本地,但是无奈视频是flash播放的,不能在开发者工具中找到视频的绝对地址进行下载,反而是找到了个直播源,譬如:http://video.newsapp.cnr.cn/data/video/2018/7358/index.m3u8
这样的链接是直播源地址,很多电视台的流媒体或者网络直播就是采用这样的方式,优点我就不说了,请自己baidu。

准备

JDK安装
ffmpeg安装:https://blog.csdn.net/u_ascend/article/details/80418402

代码

package cn.edu.zua.common.util.audio;import cn.edu.zua.common.util.UtilTools;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;/*** AudioM3U8Downloader** @author ascend* @date 2018/06/08 11:07.*/
public class AudioM3U8Downloader {private static final Logger LOG = LoggerFactory.getLogger(AudioM3U8Downloader.class);private static final String basePath = "/tmp/";private static final int downloaderMaxSecond = 120;private AudioM3U8Downloader() {}/*** 测试方法*/public static void main(String[] args) throws Exception {byte[] bytes = downloadBytes("http://recordcdn.quklive.com/upload/vod/user1462960877450854/1527512379701708/3/video.m3u8");System.out.println(bytes.length);LOG.debug("等待2s");TimeUnit.SECONDS.sleep(2);// File file = downloadFile("http://recordcdn.quklive.com/upload/vod/user1462960877450854/1524531065801767/3/video.m3u8");// System.out.println("file.getAbsolutePath() = " + file.getAbsolutePath());}/*** 把m3u8短视频下载后提取File* @param m3u8Url 直播源地址* @return 直播源文件,File* @throws InterruptedException 中断异常* @throws IOException IO异常*/public static File downloadFile(String m3u8Url) throws InterruptedException, IOException {String fileName = UtilTools.getUUIDyyyyMMddHHmmss();File f = new File("/tmp/");if (!f.exists()) {f.mkdirs();}String fullFileName = "/tmp/" + fileName + ".mp4";String command = "ffmpeg -i " + m3u8Url + " -vcodec copy " + fullFileName + " -y";LOG.debug("执行命令:{}", command);Process process = Runtime.getRuntime().exec(command);ExecutorService executorService = Executors.newFixedThreadPool(3);getStream(executorService, process.getErrorStream(), true);getStream(executorService, process.getInputStream(), false);TimeUnit.SECONDS.sleep(10);File file = new File(fullFileName);// 最长再等待24秒for (int i = 0; i < 8; i++) {if (!file.exists()) {LOG.debug("文件不存在,重新创建...");TimeUnit.SECONDS.sleep(3);file = new File(fullFileName);}}long size = 0;final boolean[] checkFlag = {true};executorService.execute(() -> {try {TimeUnit.SECONDS.sleep(150);checkFlag[0] = false;} catch (InterruptedException e) {LOG.error("最长等待线程被中断,正常错误", e);}});int maxCount = 10;while (checkFlag[0]) {TimeUnit.SECONDS.sleep(5);long fileLength = file.length();LOG.debug("上一次监测的大小:{}, 本次监测的大小:{}", size, fileLength);if (file.length() != size) {size = file.length();TimeUnit.SECONDS.sleep(5);} else {if (fileLength == 0 && maxCount-- > 0) {continue;} else {LOG.debug("退出循环...");checkFlag[0] = false;}}}process.destroy();executorService.shutdownNow();LOG.info("文件下载成功:{}", file.getAbsolutePath());return file;}/*** 把m3u8短视频下载后提取byte数组,并且删除临时文件* @param m3u8Url 直播源地址* @return byte[],从文件中提取的字节数组* @throws InterruptedException 中断异常* @throws IOException IO异常*/public static byte[] downloadBytes(String m3u8Url) throws InterruptedException, IOException {File file = downloadFile(m3u8Url);LOG.debug("字节数组方法下载调用成功:{}, 文件大小:{}", file.getAbsolutePath(), file.length());LOG.debug("睡眠2秒钟,把文件转换为字节数组");TimeUnit.SECONDS.sleep(2);FileInputStream input = FileUtils.openInputStream(file);byte[] bytes = IOUtils.toByteArray(input);input.close();LOG.info("返回文件数组!!文件长度:{}", bytes.length);// 删除下载后的文件if (file.exists()) {LOG.debug("文件存在,删除文件!");if (Files.deleteIfExists(Paths.get(file.toURI()))) {LOG.debug("删除成功");}else {LOG.debug("删除失败");}}return bytes;}private static void getStream(ExecutorService executorService, final InputStream inputStream, final boolean printFlag) {executorService.execute(() -> {BufferedInputStream in = new BufferedInputStream(inputStream);byte[] bytes = new byte[1024];try {while (in.read(bytes) != -1) {String s = new String(bytes, 0, bytes.length);if (printFlag) {
//                            LOG.error("ffmpeg:error when downloading!\ninfo:"+s);}
//                        LOG.debug("read from inputstream:{}", s);}} catch (IOException e) {LOG.error("读取下载流失败", e);} finally {try {in.close();} catch (IOException e) {LOG.error("关闭读取流失败:", e);}}});}
}

看这里,看这里
文章总目录:博客导航

M3U8下载,直播源下载,FLASH下载(三)-直播源下载相关推荐

  1. 传奇游戏源码 Linux版本 传奇源码 Linux版 三端源码和搭建, 然后打包生成APP

    此源码牛逼拉萨, 因为鄙人玩了好一段时间, 故此搞篇文章记录下几个技术关键点 Linux架设教程 先决条件: CentOS 7 Nginx 1.8 mysql 5.6 php 5.6 建议使用 IP: ...

  2. 网狐二次开发仿爱玩棋牌三网通源码全套安装源码下载

    网狐二次开发仿爱玩棋牌三网通源码全套安装源码安装过程: 0. 环境 OS:Windows 10,64 bit: 显卡:NVIDIA GeForce GTX 1050Ti,显卡查看方法:计算机[设备管理 ...

  3. 最新仿淘宝B站购物直播小程序+带货完整PHP源码下载

    正文: 最新仿淘宝B站购物直播小程序+带货完整PHP源码下载,由于演示图太长了,所以我分别载图了两张,完整的演示图直接发压缩包了,有兴趣自行去查看. 当前版本已经修复直播间相关的一些BUG,还有商品新 ...

  4. flash高科技php网站源码下载,Flash小游戏PHP源码

    项目包里有两种版本, 第一种是:UTF-8 PHP版本 第二种是:UTF-8 伪静态版本(如果空间支持,强烈建议使用此版本,对搜索引擎友好) 开源项目:flash游戏源码,小游戏PHP源码,休闲fla ...

  5. 2014年最新720多套Android源码2.0GB免费一次性打包下载

    之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年3月份开始不断整理源码区和其他网站上的android源码,目前总共有720套左右,根据实现的功能被我分成了100多个类,总共 ...

  6. linux本地yum源与软件包管理,【Linux系统中的】本地yum源的搭建与使用yum源进行软件的下载...

    前言: 当我们在使用Linux系统时,有时需要一些辅助工具帮助我们实现某项功能, 例如画图.wps.等功能,而这些功能并不是系统自带的,需要我们下载相关的 软件,那如何去下载这些软件那,这里我们不得不 ...

  7. 安卓系统源码编译系列(一)——下载安卓系统源码教程

    最近需要编译安卓系统,咨询了一个编译过安卓系统的朋友,说是下载源码就得下载两天,于是做好了长期抗战的准备,开始了下载安卓源码的旅程.在刚开始下载时,可以参照的内容只有官方教程,于是跟着官方教程一步一步 ...

  8. android源码大全 IOS游戏源代码打包下载 小游戏|视频教程 微信小程序源码带后台全套|公众号平台

    不断更新中,下面是2017-12-22更新部分 IOS_源码及视频一小部分: 开发环境:Xcode 基于cocos2d的tweejump跳跃游戏ios经典游戏源码.rar  https://pan.b ...

  9. 下载、编译官方Android 4.1.2 源码

    (一).搭建编译环境 1. 查看linux编译环境软件版本 1.1 python版本 $ python -V 1.2 make版本 $ make -v GNU Make 3.81 Copyright ...

  10. Ubuntu20.04软件主要管理工具包详细介绍:离线安装dpkg、在线安装apt、源码安装(适用于Github程序下载)

    Ubuntu20.04软件主要管理工具包详细介绍:离线安装dpkg.在线安装apt.源码安装(适用于Github程序下载) 一.离线安装dpkg命令 二.在线安装apt命令 三.软件包的源码安装过程 ...

最新文章

  1. 浏览器访问网页过程中发生了什么?(转)
  2. Spring IOC 之 加载 Bean
  3. 微信小程序页面文字超出一行隐藏,文字超出两行隐藏。
  4. linux系统怎么建ftp服务器地址,Ubuntu Linux系统建立FTP服务器方法步骤
  5. hadoop的开发工具_Hadoop开发工具简介
  6. 追踪 Kubernetes 中的网络流量
  7. Arrays.asList()和Collections.singletonList()比较
  8. placement new操作符
  9. nacos 本地测试_本地调试和服务器调试都无法连通-问答-阿里云开发者社区-阿里云...
  10. Ubuntu18.04安装Oracle11g
  11. Python-移位密码、仿射变换解密
  12. 计算机优化英语课堂教学,多媒体课件优化英语课堂的反思性研究
  13. 【历史上的今天】3 月 8 日:游戏机之父诞辰;搜索技术之父出生;MIT 公开演示旋风计算机
  14. WPS标题段前间距设置无效解决方案
  15. 硬方案——几种实用的恒流源电路设计方案,敬请收藏(运放、三极管在手,让你玩出多种花样)
  16. Freeswitch呼入及呼出录音问题
  17. centos安装unrar并使用
  18. 云产品经理相关技术知识(一)
  19. 应用统计学与R语言实现学习笔记(三)——描述性统计
  20. 【历史上的今天】10 月 6 日:互联网先驱诞生日;莲花公司宣布上市

热门文章

  1. vs2010mfc单文档中添加对话框中的控件
  2. Opencv查找轮廓并绘制
  3. Tkinter注册界面判断用户名是否唯一的合法性验证(Python3.7)
  4. 监控oracle某条sql语句,Oracle-常用监控SQL语句
  5. 优雅的断开连接--shutdown()
  6. python基础:购物车代码
  7. 2022年C语言程序设计题库习集带答案(史上最全版)
  8. CSS外链怎么写,css外链式基本写法是什么
  9. 超详细 CSS动画-animation
  10. 警告!不要购买安桥Htx22hdx直到你读这