视频  http下载代码 dn.go(注意:代码很ugly,没怎么花时间)

总体感觉特别简单,网上看了下 net/http ,io这2个库的使用, 几分钟就写完了,感觉cpp 在做工具这块 开发效率的确差太多(没有轮子的话)。

再放一个 go example 网站,https://gobyexample.com/

package main  

    import (
"fmt"
"io"
"net/http"
"os"
"strconv"
)
/*
var (
//url = "http://flv5.bn.netease.com/live163/store/208588/serverpush_18783_1521024752481_208588_0-1.ts"
url string = "http://flv5.bn.netease.com/live163/store/208588/serverpush_18783_1521024752481_208588_0-"
url_suffix string = ".ts"
)
*/
func main() {
fmt.Println("download begin.....") url := "http://flv5.bn.netease.com/live163/store/208588/serverpush_18783_1521024752481_208588_0-"
url_suffix := ".ts" for i := ; i <= ; i++ { str_index := strconv.Itoa(i) // 通过Itoa方法转换
//str2 := fmt.Sprintf("%d", i) // 通过Sprintf方法转换
//fmt.Println(str_index) // 打印str1 strFinal := url+str_index+ url_suffix res, err := http.Get(strFinal)
if err != nil {
panic(err)
}
f, err := os.Create(str_index+url_suffix)
if err != nil {
panic(err)
}
fileSize,writeErr := io.Copy(f, res.Body) fmt.Println(strFinal + " download done,", "file size(byte)=", fileSize)
if writeErr != nil {
fmt.Println(strFinal + " download failed ", "errorInfo=", writeErr.Error())
panic(err)
}
} fmt.Println("download finish.") }

-------------------

因为有些m3u8不是有规则的,

所以又写了新版本 ,按行 读取m3u8,逐行读取 ts文件(ffmpe  concat 合并文件,所以还要写  merge.txt)

ffmpeg文件合并
merge.txt 格式

```txt
file 1.ts
file 2.ts
...

file 100.ts

```

> .\ffmpeg.exe  -y -f concat -safe -1 -i .\record.m3u8-merge.txt -c copy -bsf:a aac_adtstoasc dst.mp4

代码

package main  

    import (
"fmt"
"io"
"net/http"
"os"
//"strconv"
"bufio"
"strings"
"os/exec" "log"
) func MergeVideo(mergeFile, videoName string) int{
var nRetsult int
nRetsult=0 fmt.Printf("Merging video parts into %s\n", videoName)
cmd := exec.Command("ffmpeg", "-y", "-f", "concat", "-safe", "-1",
"-i", mergeFile, "-c", "copy", "-bsf:a", "aac_adtstoasc", videoName,
)
err := cmd.Run()
if err != nil {
log.Fatal(err)
} nRetsult=1
return nRetsult
} func downloadByM3u8File(strM3u8FilePath string) int{
var nRetsult int
nRetsult=0 var strSlices []string
var strFilename string M3u8file, err := os.Open(strM3u8FilePath)//打开文件 //check m3u8 Is Exist //create ffmpeg merge file
mergeFile := strM3u8FilePath + "-merge.txt" file, _ := os.Create(mergeFile) //if exist ,truncate defer M3u8file.Close() //打开文件出错处理
if nil == err {
buff := bufio.NewReader(M3u8file) //读入缓存
for {
//line, isPrefix,err := buff.ReadLine() httpAddress, err := buff.ReadString('\n') //以'\n'为结束符读入一行
if err != nil || io.EOF == err {
break
} //if(strings.Contains(httpAddress, ".ts")){
if(strings.Contains(httpAddress, "http")){
httpAddress = strings.TrimSpace(httpAddress)
httpAddress = strings.TrimRight(httpAddress,"\n") strSlices = strings.Split(httpAddress,"/") //分离成多个 slices
strFilename = strSlices[len(strSlices)-1] //取最后 的文件名 //write ffmpeg merge file
file.Write([]byte(fmt.Sprintf("file %s\n", strFilename))) res, err := http.Get(httpAddress) //获取失败?
if err != nil {
panic(err)
} TsFile, err := os.Create(strFilename)
if err != nil {
panic(err)
} fileSize,writeErr := io.Copy(TsFile, res.Body)
TsFile.Close() fmt.Println(strFilename + " download done,", "file size(byte)=", fileSize)
if writeErr != nil {
fmt.Println(strFilename + " download failed ", "errorInfo=", writeErr.Error())
panic(err)
} //此行有ts文件,应该下载
nRetsult++
fmt.Print(httpAddress) //可以对一行进行处理
}
//fmt.Print(line) //可以对一行进行处理 }
}else{
fmt.Println(strM3u8FilePath , " file do not exist")
} file.Close() return nRetsult
} /*
// M3u8URLs get all urls from m3u8 url
func M3u8URLs(uri string) []string {
html := request.Get(uri)
lines := strings.Split(html, "\n")
var urls []string
for _, line := range lines {
line = strings.TrimSpace(line)
if line != "" && !strings.HasPrefix(line, "#") {
if strings.HasPrefix(line, "http") {
urls = append(urls, line)
} else {
base, _ := url.Parse(uri)
u, _ := url.Parse(line)
urls = append(urls, fmt.Sprintf("%s", base.ResolveReference(u)))
}
}
}
return urls
}
*/
func main() { //要设置launch.json的 argv 才能debug 用参数
if( len(os.Args)!= 2 ){
fmt.Println("参数不正确,请确认输入m3u8文件。 格式如: 1.exe a.mau8")
return
} /*
argsWithProg := os.Args
argsWithoutProg := os.Args[1:]
*/ arg := os.Args[1] //第二个参数
fmt.Println(arg) //还需要 判断输入的参数个数, fmt.Println("download begin.....") nRet := downloadByM3u8File(arg)
fmt.Println("已下载共 %d 个ts文件",nRet) //MergeVideo("1.mp4","record.m3u8-merge.txt") fmt.Println("download finish.") }

1.代码可以用格式处理下,

2.代码比较基础,没时间写异常, 简单能用就行。

附: 一些网站如何获取m3u8 文件

1> 学堂在线( 用flash 播放器)

1.打开网站http://www.xuetangx.com/event/cvpr2017
F12查看html代码 <div class="video_container">
<div class="wrap">
<div class="title" id="videoTitle">微软亚洲研究院创研论坛 CVPR 2017 论文分享会</div>
<div class="video_wrap cf" id="video_container"><iframe src="http://cloud.quklive.com/cloud/a/embed/1497351554750965" allowfullscreen="" width="720" height="460" frameborder="0"></iframe></div>
<div class="video_function cf">
<ul class="video_function_btn fr cf">
<li><a href="javascript:" id="infoShare"><span class="icon_share"></span><span>分享到...</span></a></li>
</ul>
</div>
</div>
</div> 注意:
"video_container" div 中有 <iframe src="http://cloud.quklive.com/cloud/a/embed/1497351554750965" http://cloud.quklive.com/cloud/a/embed/1497351554750965就是码流地址,但是 是js加密的, 2. 打开 http://cloud.quklive.com/cloud/a/embed/1497351554750965
F12查看js 代码 在 function onJSBridge(playerId, event, data) {
switch(event) {
case "onJavaScriptBridgeCreated":
case "ready":
DM.watching("1497351554750965","http://recordcdn.quklive.com/broadcast/activity/1497351554750965/record.m3u8","record");
break;
default:;
break;
}
} 这个就是我们的码流 文件了, 用http下载把上面TS文件下载 下来,再用ffmpeg 合并就可以了。

2>上直播(HTML5)

http://shangzhibo.tv/watch/5833145
网站html 直接查找m3u8(当然用video, player src,等关键字 搜索)
https://shangzhibo-img.b0.upaiyun.com/client/user/100994/1526289188264/1526289188242_Session1GANandSynthesis-processed.m3u8

3>网易云音乐(HTML5)

网易云直播

http://live.163.com/room/173789.html

视频解析,可以得到 flv5.bn.netease.com/live163/store/208588/serverpush_18783_1521024752481_208588_208588_20180314185233_20180314202528_0.m3u8

4> 抖音 (HTML5)

5> bilibili

再附上一个github 项目,里面有一些其他网站  视频下载方式

https://github.com/iawia002/annie

Supported Sites

Site URL

go http 下载视频(TS码流文件)(推荐一个网站学习 go example)的更多相关文章

  1. 关于ES、PES、PS/TS 码流

    一.基本概念 )ES   ES--Elementary  Streams  (原始流)是直接从编码器出来的数据流,可以是编码过的视频数据流(H.264,MJPEG等),音频数据流(AAC),或其他编码 ...

  2. Wireshark Lua: 一个从RTP抓包里导出H.264 Payload,变成264裸码流文件(xxx.264)的Wireshark插件

    Wireshark Lua: 一个从RTP抓包里导出H.264 Payload,变成264裸码流文件(xxx.264)的Wireshark插件 在win7-64, wireshark Version ...

  3. h.264码流解析_一个SPS的nalu及获取视频的分辨率

    00 00 00 01 67 42 00 28 E9 00  A0 0B 77 FE 00 02 00 03 C4 80  00 00 03 00 80 00 00 1A 4D 88  10 94 0 ...

  4. 将腾讯视频客户端缓冲的文件转换为一个MP4格式文件

    打开腾讯视频windows客户端,播放要下载的视频,逐步快进使其缓冲完毕: 按照下图所示,复制缓存路径: 在cmd.exe的界面中输入“cd C:\854456b6d5a187ff3c0f553918 ...

  5. 推荐一个网站——聚合了微软的文件的Knowledge Base下载地址

    Microsoft Files是一个微软的文件数据库,从这里可以很方便的找到各个文件版本对应的下载链接. 比如今天debug需要找一个特定版本的sos.dll,从这个网站就很方便的给出了这个sos.d ...

  6. 【转】打包AAC码流到FLV文件

    AAC编码后数据打包到FLV很简单.1. FLV音频Tag格式                              字节位置    意义0x08,                         ...

  7. 【视频开发】【Live555】live555实现h264码流RTSP传输

    1.概述 liveMedia 库中有一系列类,基类是Medium,这些类针对不同的流媒体类型和编码. 其中的StreamFrame类文件(如MPEG4VideoStreamFramer)为流传输关键. ...

  8. 【视频编解码·学习笔记】4. H.264的码流封装格式

    一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...

  9. 【视频编解码·学习笔记】4. H.264的码流封装格式 & 提取NAL有效数据

    一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...

随机推荐

  1. 整合Settings.bundle显示版本信息

    本文转载至 http://www.cocoachina.com/ios/20141103/10112.html iOS开发XCode版本管理Debug开发Tips   现在你有一个App,你同事的iP ...

  2. C#中反射type记录

    写代码的时候经常需要使用反射相关的东西例如:分析现有类型自动生成类, 或者为现有的类自动增加一些功能总结了一点点经验以ClassA  a; 为例1. 通过typeof(ClassA) 或者 a.Get ...

  3. 九度OJ 1074:对称平方数 (数字特性)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4804 解决:2173 题目描述: 打印所有不超过n(n<256)的,其平方具有对称性质的数. 如11*11=121 输入: 无任何输 ...

  4. nohup COMMAND > FILE

    nohup  --help nohup(1) - Linux man page https://linux.die.net/man/1/nohup

  5. mysql系列之2.mysql多实例

    使用场景 资金紧张; 并发访问不大; 门户网站; 实现 生产硬件配置: mem 32G / 双cpu 8核 / 磁盘6*600G sas 15k, 2-3个实例 安装组件 #yum install n ...

  6. 【题解】 P5021赛道修建

    [题解]P5021 赛道修建 二分加贪心,轻松拿省一(我没有QAQ) 题干有提示: 输出格式: 输出共一行,包含一个整数,表示长度最小的赛道长度的最大值. 注意到没,最小的最大值,还要多明显? 那么我 ...

  7. BZOJ2328: [HNOI2011]赛车游戏

    BZOJ2328: [HNOI2011]赛车游戏 Description 题解Here! 一开始被题面那一长串的描述吓到了,一直没敢做... 然后尝试着硬着头皮读懂题面. 然后...这不是贪心么??? ...

  8. Android开发之ListView添加多种布局效果演示

    在这个案例中展示的新闻列表,使用到ListView控件,然后在适配器中添加多种布局效果,这里通过重写BaseAdapter类中的 getViewType()和getItemViewType()来做判断 ...

  9. margin的相关属性及应用

    1.margin常见问题: ①IE6下双边距   (不推荐使用float+margin,可用padding替代) 详见<css浏览器兼容问题集锦>之4.IE6中margin双边距 ②IE6 ...

  10. cinder挂载卷的过程原理

    LVM名称介绍 PV:物理磁盘 VG:卷组,多个PV可以组成一个VG,一个VG可以划分成多个LV(逻辑卷). PP:物理区块,将一个VG逻辑的划分成连续的小块. LP:逻辑区块,若干个PP组成一个LP ...