视频  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. JavaScript系列问题

    JavaScript系列问题:  0.javascript 基础教程[温故而知新一] 1.通过JS变更页面字体的大小 2.图片压缩优化能有效提高网站浏览速度

  2. linux下的显示有中国农历的日历ccal

    1.linux下的显示有中国农历的日历ccal

  3. StringBuilder的append、StringBuffer的append和String str = "a"+"b"的区别?

    大家都知道String+String会开销额外的系统资源,粗略的原因是String是不可变类,每一步操作都会返回新的String变量,占用空间及时间. 其实我的理解不是这样的,我们来看看String+ ...

  4. diy文件系统上创建文件的流程

    [0]README 0.1) source code are from orange's implemention of a os , and for complete code , please v ...

  5. ubuntu 12.10 笔记

    笔记 more ec_unitouch.log |grep Thread-4 筛选日志 打开命令行终端 ctrl + alt + t     查看版本号 : sudo lsb_release -a t ...

  6. HDU 5343 MZL's Circle Zhou 后缀自动机+DP

    MZL's Circle Zhou Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  7. detached HEAD state

    1 detached HEAD state指的是什么 正常情况下,HEAD指向一个branch,而branch又指向一个commit. detached HEAD state指的是HEAD指针没有指向 ...

  8. Python中高层次的数据结构,动态类型和动态绑定,使得它非常适合于快速应用开发,也适合于作为胶水语言连接已有的软件部件。

    https://github.com/jhao104/proxy_pool/blob/master/doc/introduce.md 3.代码模块 Python中高层次的数据结构,动态类型和动态绑定, ...

  9. GIT笔记:将项目发布到码云

    GIT笔记:将项目发布到码云 发布步骤 1.码云创建项目 记录下项目的远程地址: https://gitee.com/mrsaber/ms_supplyAndSale.git 2.在本地创建GIT仓库 ...

  10. 项目log4j日志管理详解

    项目log4j日志管理详解 log4j日志系统在项目中重要性在这里就不再累述,我们在平时使用时如果没有特定要求,只需在log4j.properties文件中顶入输出级别就行了.如果要自定义输出文件,对 ...