缘起
之前下载视频用的you-get,但是b站一直下不了,优酷也经常出问题,所以接触到lulu https://github.com/iawia002/Lulu 这个也是基于you-get 直接 pip install lulu,但是作者不维护了,新出了个 https://github.com/iawia002/a… 这个不是python 开发的 ,而是 go ,通过 go get github.com/iawia002/annie 来安装 ,比如之前用lulu下载电影优酷的《大话西游》,这里推荐下优酷的2个播主,上传了几百个经典香港电影 :
经典香港电影
东方不败影院
$ lulu -i https://v.youku.com/v_show/id_XMzY4OTMxMTYyMA==.html?
It seems that your ffmpeg is a nightly build.
Please switch to the latest stable if merging failed.
site: 优酷 (Youku)
title: 大话西游之大圣娶亲【周星驰】【1080p】【国语中字】
streams: # Available quality and codecs
[ DEFAULT ] _________________________________
- format: mp4hd3v2
container: mp4
video-profile: 1080P
size: 1777.4 MiB (1863787718 bytes)
m3u8_url: http://pl-ali.youku.com/playlist/m3u8?vid=XMzY4OTMxMTYyMA&type=mp4hd3v3&ups_client_netip=756495b7&utid=31o%2FFP58k0kCAXVklbeqyp8h&ccode=0502&psid=f9aac3a8a0c035a6baa3a745a49c2487&duration=5983&expire=18000&drm_type=1&drm_device=7&ups_ts=1538813154&onOff=0&encr=0&ups_key=5310a4e7d0e7795209d27a8b117c8a04
# download-with: lulu --format=mp4hd3v2 [URL]
- format: mp4hd2v2
container: mp4
video-profile: 超清
size: 906.9 MiB (950999892 bytes)
m3u8_url: http://pl-ali.youku.com/playlist/m3u8?vid=XMzY4OTMxMTYyMA&type=mp4hd2v3&ups_client_netip=756495b7&utid=31o%2FFP58k0kCAXVklbeqyp8h&ccode=0502&psid=f9aac3a8a0c035a6baa3a745a49c2487&duration=5983&expire=18000&drm_type=1&drm_device=7&ups_ts=1538813154&onOff=0&encr=0&ups_key=5310a4e7d0e7795209d27a8b117c8a04
# download-with: lulu --format=mp4hd2v2 [URL]
- format: mp4hd
container: mp4
video-profile: 高清
size: 560.3 MiB (587487098 bytes)
m3u8_url: http://pl-ali.youku.com/playlist/m3u8?vid=XMzY4OTMxMTYyMA&type=mp4hdv3&ups_client_netip=756495b7&utid=31o%2FFP58k0kCAXVklbeqyp8h&ccode=0502&psid=f9aac3a8a0c035a6baa3a745a49c2487&duration=5983&expire=18000&drm_type=1&drm_device=7&ups_ts=1538813154&onOff=0&encr=0&ups_key=5310a4e7d0e7795209d27a8b117c8a04
# download-with: lulu --format=mp4hd [URL]
- format: 3gphd
container: mp4
video-profile: 渣清
size: 184.1 MiB (193030164 bytes)
m3u8_url: http://pl-ali.youku.com/playlist/m3u8?vid=XMzY4OTMxMTYyMA&type=3gphdv3&ups_client_netip=756495b7&utid=31o%2FFP58k0kCAXVklbeqyp8h&ccode=0502&psid=f9aac3a8a0c035a6baa3a745a49c2487&duration=5984&expire=18000&drm_type=1&drm_device=7&ups_ts=1538813154&onOff=0&encr=0&ups_key=e8361d25bb6ea3bb70a8a81a94ed5b50
# download-with: lulu --format=3gphd [URL]
- format: mp4sd
container: mp4
video-profile: 标清
size: 279.0 MiB (292555710 bytes)
m3u8_url: http://pl-ali.youku.com/playlist/m3u8?vid=XMzY4OTMxMTYyMA&type=flvhdv3&ups_client_netip=756495b7&utid=31o%2FFP58k0kCAXVklbeqyp8h&ccode=0502&psid=f9aac3a8a0c035a6baa3a745a49c2487&duration=5984&expire=18000&drm_type=1&drm_device=7&ups_ts=1538813154&onOff=0&encr=0&ups_key=e8361d25bb6ea3bb70a8a81a94ed5b50
# download-with: lulu --format=mp4sd [URL]
开始下载mp4hd 格式,大小560M
$ lulu --format=mp4hd https://v.youku.com/v_show/id_XMzY4OTMxMTYyMA==.html?
It seems that your ffmpeg is a nightly build.
Please switch to the latest stable if merging failed.
site: 优酷 (Youku)
title: 大话西游之大圣娶亲【周星驰】【1080p】【国语中字】
stream:
- format: mp4hd
container: mp4
video-profile: 高清
size: 560.3 MiB (587487098 bytes)
m3u8_url: http://pl-ali.youku.com/playlist/m3u8?vid=XMzY4OTMxMTYyMA&type=mp4hdv3&ups_client_netip=756495b7&utid=OVs%2FFCNJrjgCAXVklbfwfTTy&ccode=0502&psid=d311f534cb94393bef9139f8653f6a20&duration=5983&expire=18000&drm_type=1&drm_device=7&ups_ts=1538813244&onOff=0&encr=0&ups_key=328b76a03e2f827a1465b0428813b011
# download-with: lulu --format=mp4hd [URL]
Downloading 大话西游之大圣娶亲【周星驰】【1080p】【国语中字】.mp4 ...
0.2% ( 1.4/560.3MB) ├──────────────────────────────────────┤[ 1/16] 0 B/sl 100% (560.3/560.3MB) ├██████████████████████████████████████┤[16/16] 372 kB/s
Merging video parts...
其实就是用ffmpeg下载m3u8文件,但是也经常出问题
$ lulu -i https://v.youku.com/v_show/id_XMzY4OTMxMTYyMA==.html
lulu: ▒ͻ▒▒▒▒▒Ȩ▒▒▒▒,201
It seems that your ffmpeg is a nightly build.
Please switch to the latest stable if merging failed.
然后用annie 看看 ,注意先把bin 加入环境变量
λ annie -i https://v.youku.com/v_show/id_XMzY4OTMxMTYyMA==.html
Site: 优酷 youku.com
Title: 大话西游之大圣娶亲【周星驰】【1080p】【国语中字】
Type: video
Streams: # All available quality
[mp4hd3] -------------------
Quality: mp4hd3 1920x1080
Size: 1777.45 MiB (1863787718 Bytes)
# download with: annie -f mp4hd3 ...
[mp4hd2] -------------------
Quality: mp4hd2 1280x720
Size: 906.94 MiB (950999892 Bytes)
# download with: annie -f mp4hd2 ...
[mp4hd] -------------------
Quality: mp4hd 960x540
Size: 560.27 MiB (587487098 Bytes)
# download with: annie -f mp4hd ...
[flvhd] -------------------
Quality: flvhd 640x360
Size: 279.00 MiB (292555710 Bytes)
# download with: annie -f flvhd ...
[3gphd] -------------------
Quality: 3gphd 480x270
Size: 184.09 MiB (193030164 Bytes)
# download with: annie -f 3gphd ...
go生成的可执行文件就一个annie.exe,没有其他依赖,只要把这个文件下载就能用,太方便了,于是开始学习下 golang
Go的主要特点有哪些?
-类型安全 和 内存安全
-以非常直观和极低代价的方案实现 高并发
-高效的垃圾回收机制
-快速编译(同时解决C语言中头文件太多的问题)
-为多核计算机提供性能提升的方案-UTF-8编码支持
只有 package名称为 main的包可以包含main 函数
-一个可执行程序有且仅有 一个main 包
通过 import关键字来 导入其它非 main包
使用 大小写 来决定该 常量、 变量、类型、接口、结构或函数 是否可以被外部 包所调 用:根据约定,函数名首字母 小写 即为pri vate
不可以用 数字代表true或false
其它值 类型:- array、struct、string
-引用类型:- slice、map、chan
-接口类型:inteface
-函数类型:func
全局变量的 声明不 可以省略 var,但可使用 并行方式
局部变 量不可以使用 var () 的方式简写,只能使用 并行方式
Go中不存在隐式转换 ,所有类型转换必须显式声明-转换只 能发 生在两种相互兼容 的类型之间
常量 表达 式中的 函数必须是内置函数
在Go当中不支持指针运 算以及 ”->”运算符,而直接采用”.”选择符来 操作指针目标对 象的成员-操作符”&”取变量地址 ,使用 ”*”通过指针间接访问目 标对象-默认 值为 nil 而非 NULL
数组长度也是类型的一部分,因此具有不同长度的数组 为不同类型
-注意区分指向数组的指针 和指针数组
Go 函数 不支持 嵌套、重载和默认参数
defer的执行 方式 类似其它语言中的析构函数,在函数体执行结束后按照调用顺序的相反顺序逐个执行
-即使函数发生严重 错误也会执行-支持匿名函数的调用-常用于资源 清理、文件关闭、解锁以及记 录时间等 操作
-通过与 匿名函数配 合可在return之后修改函数 计算结果
-如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即已 经获得了拷贝,否则则 是引用某个变 量的 地址
-Go 没有异常机制,但有 panic/recover 模式来处理错误
-Panic 可以在任何地方引发, 但reco ver只有在defer调用的 函数 中有效
然后熟悉语法,说到这个,简直奇葩,跟PHP py完全不是一个套路,一个单引号 双引号混了就失败,先定义package ,如果不是需要执行的编译文件,不能为main ,比如learn/study/test.php package study
run.go import learn/study import导入的是目录 ,导入的包如果不用还不行,定义变量需要指定类型 ,比如var a int =3 const b string = “abc” type long float64
var c byte=’a’
这里要说下字符和字符串类型 ,字符是单个字符,用单引号,字符串是多个字符组成,用双引号,不能混用, 这的奇葩语法。
src 存放源代码(比如:.go .c .h .s等)
pkg 编译后生成的文件(比如:.a)
bin 编译后生成的可执行文件(为了方便,可以把此目录加入到 $PATH 变量中,如果有多个gopath,那么使用${GOPATH//://bin:}/bin添加所有的bin目录)很多Go命令都依赖于此变量,例如go get命令会将获取到的包放到GOPATH中。
如果是普通包,当你执行go build之后,它不会产生任何文件。如果你需要在$GOPATH/pkg下生成相应的文件,那就得执行go install了
如果是main包,当你执行go build之后,它就会在当前目录下生成一个可执行文件。如果你需要在$GOPATH/bin下生成相应的文件,需要执行go install。
go build会忽略目录下以“_”或“.”开头的go文件。
go install 这个命令在内部实际上分成了两步操作:第一步是生成结果文件(可执行文件或者.a包),第二步会把编译好的结果移到$GOPATH/pkg或者$GOPATH/bin。
Go语言中字符串的可以使用双引号( ” )或者反引号( ` )来创建。 一个单一的字符可以用一个单一的rune来表示
不能使用var i bool,j string = true, “hello”进行赋值
var myMap map[string]string // 字典声名,声明的map是空值,需要用make()创建
myMap = make(map[string]string)
// 匿名函数直接执行, 直接在函数定义后面加上参数即可
func(x,y int)int{
return x+y
}(2,3) // 传入参数2,3运行
// 匿名函数赋值
f := func(x,y int)int{
return x+y
}
type Myint int
func (m Myint)Less(b Myint) bool{
return m < b
}
var a Myint = 1
if a.Less(2){ // 对天显示的类型2会自动处理成相应类型
// do something
}
var v1 interface{} = …
switch v := v1.(type) {
case int:
// v为 int
case string:
// v为 string
//…
}
value, ok := tes[“a”].(string) // “abc”, true
len(s) 字符串s中的字节数
len([]rune(s)) 字符串s中字符的个数,可以使用更快的方法utf8.RuneCountInString()
[ ]rune(s) 将字符串s转换为一个unicode值组成的串
string(chars) chars类型是[]rune或者[]int32, 将之转换为字符串
[ ]byte(s) 无副本的将字符串s转换为一个原始的字节的切片数组,不保证转换的字节是合法的UTF-8编码字节 &用于取地址,*用于解引用,也就是获取指针指向的值。 数组是一个定长的序列,其中的元素类型相同。多维数组可以简单地使用自身为数组的元素来创建。 数组是按值传递的(即是传递的副本),而切片是引用类型,传递切片的成本非常小,而且是不定长的。而且数组是定长的,而切片可以调整长度。
x := int16(2345) // 声明一个类型为int16的整数,其值为2345
y := int32(x) // 将int16类型的整数转换为int32类型
a := uint16(6500) // 声明一个类型为uint16类型的整数
b := int16(a) // 转换为int16类型,虽然能转换成功,但是由于6500超过in16类型的范围,会导致结果错误,b的值为 -536
type StringsSlice []string 将[]string(string类型的切片)声明为StringSlice类型。
interface{} 类型表示一个空接口,任何类型都满足空接口。也就是说 interface{} 类型的值可以用于表示任意 Go 语言类型的值。
var i interface{} = 99 // 创建一个interface{}类型,其值为99
var s interface{} = []string{"left", "right"}
j := i.(int) // 我们假设i是兼容int类型,并使用类型断言将其转换为int类型
Go 编译器不允许声明导入某个包却不使用。下划线让编译器接受这类导入,并且调用对应包内的所有代码文件里定义的init函数。
结构体来实现接口 通过接口调用 var name interface{}可表示任意类型 name=1 name.(int) name=’a’ switch name.(type) 类型断言 接口是方法的集合 go install m.go 安装到$gobin 目录 ,然后可以直接运行生成的文件 go get -u github.com/tet 更新代码 五大受损,
main 函数是main包才定义的,而且不能手动调用,在init后执行,相当PHP的构造函数 ,但是没有参数和返回值,一个简单的demo
package main
import fm "fmt"
var d =1
const ( // 常量组
a, b = 10, 100
c bool = false
)
func main() {
power := getPower()//函数内才能不用var声明变量
name:="test"//下面没有用到还会失败!!!,但是全局变量a不会
fm.Printf(" power is over %d\n",power)
}
func getPower() int {
return 9001
}
go run test.go
程序正常退出的代码为 0 即 Program exited with code 0;如果程序因为异常而被终止,则会返回非零值,如:1。这个数值可以用来测试是否成功执行一个程序。
一些常用的命令
go build 编译并安装自身包和依赖包,比如window生成EXE文件
go install 安装自身包和依赖包,安装到pkg目录
gofmt –w program.go 会格式化该源文件的代码然后将格式化后的代码覆盖原始内容, 有了这个不用担心PHP一样的带风格混乱
go doc package 获取包的文档注释
当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private )。
go居然这样实现面向对象!!!!
break 只是退出当前的循环体,而 return 语句提前对函数进行返回,不会执行后续的代码。
package表示源码所属的代码包 * 要生成GO语言可执行程序,必须要有main的package包,且必须在该包下有main()函数
同一路径下只能存在一个package**,一个package可以拆分成多个源文件组成
操作符 “&” 取变量地址,”*” 透过指针访问目标对象,关键字 defer 用于注册延迟调用。这些调用直到 return 前才被执行,还有数组,slice 没来得及学,真的有点难,下次再说了。
包管理工具 govendor go get -u -v github.com/kardianos/govendor govendor init govendor add +external 第三方下载包的工具: gopm, 这个工具解决的问题是: go get 一般是从 github 服务器, 或者 google 服务器上下载第三方库, 所以有时候网速慢,或者下载不成功 go get -u github.com/gpmgo/gopm 再使用 gopm 下载第三方库: gopm get -g -v ** 固定長度列表在Golang 里称之为数组.
長度不固定的里称之为切片,值传递 一般获取值: func (m MyExample) GetAttrName()string
指针传递一般改变值: func (m *MyExample) SetAttrAge(newAge int) 值传递和指针传递针对的是函数的传入参数究竟是拷贝入参的值进行操作还是拷贝入参的内存地址,带来的效果就是一个能改变传入的参数的值,一个不能改变传入参数的值。这两个函数没有入参和返回值
一个工程有且只有一个 main 函数作为程序的主入口
一个工程可以有多个init 函数,执行顺序和包的导入顺序相关
同一数据类型的集合可以使用下面的变量声明方式 var Infor map[string]string 单一的数据类型可以使用 变量声明的方式var Number int 表示不同的数据类型的集合 结构体
结构体可以用来表示不同的数据类型的集合, 同时可以表示用户自定义类型。 结构体可以当做是一种数据类型type Name struct{}
var Infor Name 一般都默认函数的最后一个返回值是 err。type InformationWithLabel struct {
Name string `json:"name"`
Age int `json:"age"`
} func example(arg int) (int, error) {
return arg + 1, nil
} func Errorf(format string, a …interface{}) error {
return errors.New(Sprintf(format, a...))
} 需要强制退出程序,可以使用 panic panic(nil) recover 可以接收返回的异常信息,通常和 defer 一起使用 golang 中,使用到的包需要导入,不使用的包导入,编译过程会报错。这一点和 python 很不一样。 即以GOPATG/src 为基本路径导入完整路径即可 接口在 go 语言中是一系列方法的集合 一个结构体实现了接口要求的所有的方法(方法的参数和返回值一致),那么就说这个结构体实现了这个接口 内置函数 new 按指定类型分配零值内存, 返回的是一个指针。汉字转拼音https://github.com/mozillazg/… https://github.com/mozillazg/… .(type) 只在 switch 语句里才能使用。空接口在 go 里,可以当成任意类型,意味着,比如你的函数或者方法不知道传入的参数的类型,可以直接定义为 interface{}
实践
Go语言生成二维码是如此简单
go get github.com/skip2/go-qrcode 下载源码
vi qrcode.go
package main
import "github.com/skip2/go-qrcode"
func main() {
qrcode.WriteFile("http://www.flysnow.org/",qrcode.Medium,256,"./blog_qrcode.png")
}
go run qrcode.go
推荐教程
文章:
learn-go-with-tests
https://studygolang.gitbook.i…
https://zhuanlan.zhihu.com/p/…
Go名库讲解https://github.com/Unknwon/go…
Go语言实战笔记 https://zhuanlan.zhihu.com/go…
命令行 https://github.com/sbinet/igo
golang 面试题 https://zhuanlan.zhihu.com/p/… https://yushuangqi.com/blog/2…
记录学习过程 https://zhuanlan.zhihu.com/c_…
https://github.com/chai2010/a…
https://github.com/avelino/aw…
https://github.com/golang-chi…
https://github.com/Unknwon/go…
Golang 中文学习资料 https://go.wuhaolin.cn/
https://juejin.im/entry/58bfa…
https://www.v2ex.com/t/476425…
https://golangcaff.com/
Golang做了一个命令行贪吃蛇游戏 https://zhuanlan.zhihu.com/p/…
Golang 学习笔记一 https://zhuanlan.zhihu.com/p/…
Golang学习 https://zhuanlan.zhihu.com/p/…
《Go 学习笔记》 https://hacpai.com/article/14…
在线ide https://wide.b3log.org/login https://wide.b3log.org/playgr…
Go 标准库中文文档http://cngolib.com/
Golang 速查表 https://wuyin.io/2018/06/11/g…
https://www.imooc.com/code/8247
https://golangcaff.com/docs/t…
有哪有优秀的golang库? https://www.zhihu.com/questio…
官网:https://awesome-go.com/
官网:https://golanglibs.com/ https://gocn.vip/
用 Golang 来编写 cli 程序吧 https://zhuanlan.zhihu.com/p/…
golang新手容易犯的三个错误 https://zhuanlan.zhihu.com/p/…
为什么用golang作为游戏服务端的开发语言,它的并发性如何?golang有什么优点? https://www.zhihu.com/questio…
我们说Golang牛逼都在说些什么? https://zhuanlan.zhihu.com/p/…
怎么学习 Golang? https://www.zhihu.com/questio…
如何从 PHP 过渡到 Golang? https://www.zhihu.com/questio…
golang 面试题 https://zhuanlan.zhihu.com/p/…
如果你是一个Golang面试官,你会问哪些问题? https://www.zhihu.com/questio…
golang面试笔试题(第二版) https://zhuanlan.zhihu.com/p/…
总结的一些语法和 Go 特点 https://github.com/a8m/go-lan…
Golang 介绍及踩坑系列之三 https://zhuanlan.zhihu.com/p/…
为互联网IT人打造的中文版awesome-go https://github.com/hackstoic/…
转golang开发,需满足哪些技能 https://www.zhihu.com/questio…
你见过哪些令你瞠目结舌的Golang代码技巧? https://www.zhihu.com/questio…
我的golang学习笔记 https://zhuanlan.zhihu.com/p/…
Golang 爬虫上手指南 https://zhuanlan.zhihu.com/p/…
GoLang基础语法 https://zhuanlan.zhihu.com/p/…
Golang 读写 Excel https://zhuanlan.zhihu.com/p/…
记录我的Go语言学习历程 https://github.com/xx19941215…
go cheatsheet https://devhints.io/go
https://github.com/wuxiaoxiao… https://github.com/wuxiaoxiao… https://github.com/wuxiaoxiaoshen/JianShu https://www.bilibili.com/vide…
视频教程:
后端工程师攻略 https://www.bilibili.com/vide…
https://study.163.com/course/…
https://www.bilibili.com/vide…
http://edu.51cto.com/center/c…
https://www.bilibili.com/vide…
20个小时快速入门go语言 https://www.bilibili.com/vide…
go语言与区块链教程轻松搞定Golanghttps://www.bilibili.com/vide…
Go 语言教程 【Go 编程基础】 https://www.bilibili.com/vide…
Go 语言基础实战 https://www.bilibili.com/vide…
GO实现千万级WebSocket消息推送服务https://www.imooc.com/learn/1025
20小时快速入门Go语言 https://study.163.com/course/…
https://www.imooc.com/video/1…
Go语言编程源代码 https://github.com/shiyanlou/…
【编程开发】TCP-IP基础概述及IP地址子网划分https://www.bilibili.com/vide…
【王道考研】数据结构 知识点+习题+综合真题(完结) https://www.bilibili.com/vide…
Go语言Web开发Beego框架深入浅出【黑马程序员出品】 https://www.bilibili.com/vide…
后端工程师攻略 — 06-回顾总结https://www.bilibili.com/vide…
http://www.52studyit.com/ http://www.maiziedu.com/
最后,学习之路,路漫漫其修远兮。