1 //usr/bin/env go run $0 $@; exit $?
3 // http://golangcookbook.com/chapters/running/shebang/
4 // https://gist.github.com/jemygraw/412a4fd557d875fd3037
8 //Usage: vsina http://video.weibo.com/show?fid=1034:0e906d53094c5d231bf09028af8ba9b1
12 "github.com/astaxie/beego/httplib"
23 fmt
.Println("Usage: vsina <VideoUrl>")
26 func fetch(videoUrl
string) {
27 req
:= httplib
.Get(videoUrl
)
28 resp
, err
:= req
.Response()
30 fmt
.Println("fetch video url error,", err
)
33 defer resp
.Body
.Close()
34 respData
, err
:= ioutil
.ReadAll(resp
.Body
)
36 fmt
.Println("read video url content error,", err
)
39 pattern
:= `flashvars="list=.*"`
40 regx
:= regexp
.MustCompile(pattern
)
41 flashVars
:= regx
.FindString(string(respData
))
43 size
:= len(flashVars
)
44 m3u8Url
, err
:= url
.QueryUnescape(flashVars
[16 : size
-1])
51 fmt
.Println("m3u8 playlist not found")
55 func fetchMovie(m3u8Url
string) {
56 req
:= httplib
.Get(m3u8Url
)
57 resp
, respErr
:= req
.Response()
59 fmt
.Println("fetch m3u8 playlist error,", respErr
)
62 defer resp
.Body
.Close()
63 respData
, readErr
:= ioutil
.ReadAll(resp
.Body
)
65 fmt
.Println("read m3u8 playlist content error,", readErr
)
68 videoFolder
:= fmt
.Sprintf("video_%d", time
.Now().Unix())
69 mkdErr
:= os
.Mkdir(videoFolder
, 0775)
71 fmt
.Println("mkdir for m3u8 playlist failed,", mkdErr
)
74 m3u8Uri
, _
:= url
.Parse(m3u8Url
)
76 sReader
:= strings
.NewReader(string(respData
))
77 bReader
:= bufio
.NewScanner(sReader
)
78 bReader
.Split(bufio
.ScanLines
)
80 line
:= bReader
.Text()
81 if !strings
.HasPrefix(line
, "#") {
83 tsLocalFileName
:= fmt
.Sprintf("%s/%s", videoFolder
, line
)
84 tsFileUrl
:= fmt
.Sprintf("%s://%s/%s", m3u8Uri
.Scheme
, m3u8Uri
.Host
, tsFileName
)
85 downloadTS(tsFileUrl
, tsLocalFileName
)
89 fmt
.Println("Result:", videoFolder
)
92 func downloadTS(tsFileUrl
string, tsLocalFileName
string) {
93 fmt
.Println("downloading", tsFileUrl
)
94 req
:= httplib
.Get(tsFileUrl
)
95 resp
, respErr
:= req
.Response()
97 fmt
.Println("download ts ", tsFileUrl
, "failed,", respErr
)
100 defer resp
.Body
.Close()
101 tsFp
, openErr
:= os
.OpenFile(tsLocalFileName
, os
.O_CREATE|os
.O_WRONLY
, 0775)
103 fmt
.Println("open local file", tsLocalFileName
, "failed,", openErr
)
107 _
, copyErr
:= io
.Copy(tsFp
, resp
.Body
)
109 fmt
.Println("download ts", tsFileUrl
, " failed,", copyErr
)