Skip to content
This repository was archived by the owner on Jul 9, 2019. It is now read-only.

Commit 5c0b5f2

Browse files
author
ggggle
committed
init
1 parent 29be1e9 commit 5c0b5f2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+5380
-0
lines changed

.gitignore

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Compiled Object files, Static and Dynamic libs (Shared Objects)
2+
*.o
3+
*.a
4+
*.so
5+
6+
# Folders
7+
_obj
8+
_test
9+
10+
# Architecture specific extensions/prefixes
11+
*.[568vq]
12+
[568vq].out
13+
14+
*.cgo1.go
15+
*.cgo2.c
16+
_cgo_defun.c
17+
_cgo_gotypes.go
18+
_cgo_export.*
19+
20+
_testmain.go
21+
22+
*.test
23+
*.prof
24+
.idea
25+
releases
26+
resource.syso111
27+
lzb.log
28+
*.syso

.travis.yml

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
language: go
2+
go:
3+
- 1.8.3
4+
before_script:
5+
- go get github.com/tcnksm/ghr
6+
- go get github.com/aktau/github-release
7+
script:
8+
- cd $HOME/gopath/src/github.com/Baozisoftware/luzhibo
9+
- chmod +x ./make.sh
10+
- ./make.sh
11+
- ghr -u Baozisoftware -t $GITHUB_TOKEN -replace latest releases/
12+
- github-release edit -u Baozisoftware -s $GITHUB_TOKEN -r luzhibo -t latest -n "Ver `cat ver`" -d "`cat changelog`"
13+
- exit 0
14+
notifications:
15+
email: false

7z.dll

1.53 MB
Binary file not shown.

7z.exe

437 KB
Binary file not shown.

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# liveGet
2+
3+
基于[Luzhibo-go](https://github.com/Baozisoftware/luzhibo)

api/api.go

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package api
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"log"
7+
"regexp"
8+
"strings"
9+
10+
"github.com/ggggle/luzhibo/api/getters"
11+
)
12+
13+
//LuzhiboAPI API object
14+
type LuzhiboAPI struct {
15+
Id string
16+
URL string
17+
G getters.Getter
18+
Site string
19+
SiteURL string
20+
Icon string
21+
FileExt string
22+
NeedFFmpeg bool
23+
}
24+
25+
//New 使用网址创建一个实例
26+
func New(url string) *LuzhiboAPI {
27+
var r *LuzhiboAPI
28+
g := getGetter(url)
29+
if g != nil {
30+
i := &LuzhiboAPI{}
31+
i.G = g
32+
i.URL = url
33+
i.Site = g.Site()
34+
i.SiteURL = g.SiteURL()
35+
i.Icon = g.SiteIcon()
36+
i.FileExt = g.FileExt()
37+
i.NeedFFmpeg = g.NeedFFMpeg()
38+
r = i
39+
} else {
40+
r = nil
41+
}
42+
return r
43+
}
44+
45+
//GetRoomInfo 取直播间信息
46+
func (i *LuzhiboAPI) GetRoomInfo() (id string, live bool, err error) {
47+
if i.URL == "" || i.G == nil {
48+
err = errors.New("not has url or not found getter")
49+
return
50+
}
51+
id, live, err = i.G.GetRoomInfo(i.URL)
52+
i.Id = id
53+
if Logger != nil {
54+
s := fmt.Sprintf("获取房间信息\"%s\",结果:", i.URL)
55+
if err == nil {
56+
s += fmt.Sprintf("成功(直播平台:\"%s\",房间ID:\"%s\",已开播:", i.Site, id)
57+
if live {
58+
s += fmt.Sprint("\"\".).")
59+
} else {
60+
s += fmt.Sprint("\"\".).")
61+
}
62+
} else {
63+
s += fmt.Sprint("失败(获取时出错).")
64+
s += fmt.Sprint(err.Error())
65+
Logger.Print(s)
66+
}
67+
}
68+
return
69+
}
70+
71+
//GetLiveInfo 取直播信息
72+
func (i *LuzhiboAPI) GetLiveInfo() (live getters.LiveInfo, err error) {
73+
if i.Id == "" || i.G == nil {
74+
err = errors.New("not has id or not found getter")
75+
return
76+
}
77+
live, err = i.G.GetLiveInfo(i.Id)
78+
if Logger != nil {
79+
s := fmt.Sprintf("获取直播信息\"%s\",结果:", i.URL)
80+
if err == nil {
81+
s += fmt.Sprintf("成功(直播平台:\"%s\",房间ID:\"%s\",房间标题:\"%s\",主播昵称:\"%s\",直播流地址:\"%s\".).", i.Site, i.Id, live.RoomTitle, live.LiveNick, live.VideoURL)
82+
} else {
83+
s += fmt.Sprint("失败(获取时出错).")
84+
s += fmt.Sprint(err.Error())
85+
}
86+
Logger.Print(s)
87+
}
88+
return
89+
}
90+
91+
func getGetter(url string) getters.Getter {
92+
url = strings.ToLower(url)
93+
regs := []string{"(douyu\\.tv)|((douyu)|(douyutv)\\.com)",
94+
"www\\.panda\\.tv",
95+
"zhanqi\\.tv",
96+
"longzhu\\.com",
97+
"huya\\.com",
98+
"live\\.qq\\.com",
99+
"live\\.bilibili\\.com",
100+
"quanmin\\.tv",
101+
"huajiao\\.com",
102+
"huomao\\.com",
103+
"yizhibo\\.com",
104+
"egame.qq\\.com",
105+
"chushou\\.tv",
106+
"inke\\.cn",
107+
"play\\.afreecatv\\.com",
108+
"xingyan\\.panda\\.tv"}
109+
gs := getters.Getters()
110+
for i := 0; i < len(gs); i++ {
111+
if ok, _ := regexp.MatchString(regs[i], url); ok {
112+
return gs[i]
113+
}
114+
}
115+
return nil
116+
}
117+
118+
func GetSupports() []string {
119+
gs := getters.Getters()
120+
ret := make([]string, len(gs))
121+
for i, oa := range gs {
122+
ret[i] = oa.Site()
123+
if oa.NeedFFMpeg() {
124+
ret[i] = ret[i] + "*"
125+
}
126+
}
127+
return ret
128+
}
129+
130+
var Logger *log.Logger

api/getters/afreeca.go

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package getters
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"regexp"
7+
"strings"
8+
)
9+
10+
//afreeca AfreecaTV
11+
type afreeca struct{}
12+
13+
//Site 实现接口
14+
func (i *afreeca) Site() string { return "AfreecaTV" }
15+
16+
func (i *afreeca) GetExtraInfo(string) (info ExtraInfo, err error) { return }
17+
18+
//SiteURL 实现接口
19+
func (i *afreeca) SiteURL() string {
20+
return "http://www.afreecatv.com"
21+
}
22+
23+
//SiteIcon 实现接口
24+
func (i *afreeca) SiteIcon() string {
25+
return i.SiteURL() + "/favicon.ico"
26+
}
27+
28+
//FileExt 实现接口
29+
func (i *afreeca) FileExt() string {
30+
return "ts"
31+
}
32+
33+
//NeedFFMpeg 实现接口
34+
func (i *afreeca) NeedFFMpeg() bool {
35+
return true
36+
}
37+
38+
//GetRoomInfo 实现接口
39+
func (i *afreeca) GetRoomInfo(url string) (id string, live bool, err error) {
40+
defer func() {
41+
if recover() != nil {
42+
err = errors.New("fail get data")
43+
}
44+
}()
45+
url = strings.ToLower(url)
46+
reg, _ := regexp.Compile("play\\.afreecatv\\.com/(\\w+)(/\\d+)*")
47+
id = reg.FindStringSubmatch(url)[1]
48+
tmp, err := httpGet(url)
49+
if !strings.Contains(tmp, fmt.Sprintf("szBjId = '%s'", id)) {
50+
id = ""
51+
} else {
52+
live = strings.Contains(tmp, "\"og:title\" content=\"[생]")
53+
}
54+
if id == "" {
55+
err = errors.New("fail get data")
56+
}
57+
return
58+
}
59+
60+
//GetLiveInfo 实现接口
61+
func (i *afreeca) GetLiveInfo(id string) (live LiveInfo, err error) {
62+
defer func() {
63+
if recover() != nil {
64+
err = errors.New("fail get data")
65+
}
66+
}()
67+
live = LiveInfo{RoomID: id}
68+
url := "http://play.afreecatv.com/" + id
69+
tmp, err := httpGet(url)
70+
reg, _ := regexp.Compile("nBroadNo = (\\d+)")
71+
rid := reg.FindStringSubmatch(tmp)[1]
72+
tmp, err = httpPost("http://live.afreecatv.com:8057/afreeca/player_live_api.php", "bno="+rid)
73+
json := *(pruseJSON(tmp).JToken("CHANNEL"))
74+
nick := fmt.Sprint(json["BJNICK"])
75+
title := fmt.Sprint(json["TITLE"])
76+
stpt := fmt.Sprint(json["STPT"])
77+
img := fmt.Sprintf("http://liveimg.afreecatv.com/%s.gif", rid)
78+
if stpt == "RTMP" {
79+
url = fmt.Sprintf("http://sessionmanager01.afreeca.tv:6060/broad_stream_assign.html?return_type=gs_cdn&broad_key=%s-flash-hd-rtmp", rid)
80+
} else {
81+
url = fmt.Sprintf("http://resourcemanager.afreeca.tv:9090/broad_stream_assign.html?return_type=gs_cdn&broad_key=%s-flash-hd-hls", rid)
82+
}
83+
tmp, err = httpGet(url)
84+
json = *pruseJSON(tmp)
85+
video := fmt.Sprint(json["view_url"])
86+
if stpt == "HLS" {
87+
tmp, err = httpPost("http://live.afreecatv.com:8057/afreeca/player_live_api.php", "type=pwd&bno="+rid)
88+
json = *(pruseJSON(tmp).JToken("CHANNEL"))
89+
aid := fmt.Sprint(json["AID"])
90+
video += "?aid=" + aid
91+
} else {
92+
reg, _ := regexp.Compile("rtmp://g7\\.\\w+")
93+
if reg.FindString(video) != "" {
94+
reg, _ := regexp.Compile("rtmp://([\\w\\.]+)/(\\S+)")
95+
l := reg.FindStringSubmatch(video)
96+
host := l[1]
97+
path := l[2]
98+
host = strings.Join(strings.Split(host, ".")[2:], ".")
99+
host = strings.Split(path, "/")[0] + "." + host
100+
video = fmt.Sprintf("rtmp://%s/%s", host, path)
101+
}
102+
}
103+
live.LiveNick = nick
104+
live.RoomTitle = title
105+
live.RoomDetails = ""
106+
live.LivingIMG = img
107+
live.VideoURL = video
108+
109+
if video == "" {
110+
err = errors.New("fail get data")
111+
}
112+
return
113+
}

api/getters/bilibili.go

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package getters
2+
3+
import (
4+
"errors"
5+
"strings"
6+
"github.com/buger/jsonparser"
7+
"strconv"
8+
"fmt"
9+
)
10+
11+
//bilibili Bilibili直播
12+
type bilibili struct{}
13+
14+
//Site 实现接口
15+
func (i *bilibili) Site() string { return "Bilibili直播" }
16+
17+
func (i *bilibili) GetExtraInfo(roomid string) (info ExtraInfo, err error) {
18+
defer func() {
19+
if recover() != nil {
20+
err = errors.New("fail get data")
21+
}
22+
}()
23+
infoUrl := "https://api.live.bilibili.com/room/v1/Room/get_info?room_id=" + roomid
24+
tmp, _ := httpGet(infoUrl)
25+
info.RoomTitle, _ = jsonparser.GetString([]byte(tmp), "data", "title")
26+
info.Site = "Bilibili"
27+
info.OwnerName = ""
28+
info.RoomID = roomid
29+
return
30+
}
31+
32+
//SiteURL 实现接口
33+
func (i *bilibili) SiteURL() string {
34+
return "http://live.bilibili.com"
35+
}
36+
37+
//SiteIcon 实现接口
38+
func (i *bilibili) SiteIcon() string {
39+
return i.SiteURL() + "/favicon.ico"
40+
}
41+
42+
//FileExt 实现接口
43+
func (i *bilibili) FileExt() string {
44+
return "flv"
45+
}
46+
47+
//NeedFFMpeg 实现接口
48+
func (i *bilibili) NeedFFMpeg() bool {
49+
return false
50+
}
51+
52+
//GetRoomInfo 实现接口
53+
func (i *bilibili) GetRoomInfo(url string) (id string, live bool, err error) {
54+
defer func() {
55+
if recover() != nil {
56+
err = errors.New("fail get data")
57+
}
58+
}()
59+
urlsplit := strings.Split(url, "/")
60+
fakeid := urlsplit[len(urlsplit)-1]
61+
api := "https://api.live.bilibili.com/room/v1/Room/room_init?id=" + fakeid
62+
tmp, err := httpGet(api)
63+
idInt, err := jsonparser.GetInt([]byte(tmp), "data", "room_id")
64+
id = strconv.Itoa(int(idInt))
65+
live_status, err := jsonparser.GetInt([]byte(tmp), "data", "live_status")
66+
if live_status == 1 {
67+
live = true
68+
fmt.Println(id + " live now")
69+
} else {
70+
live = false
71+
}
72+
return
73+
}
74+
75+
//GetLiveInfo 实现接口
76+
func (i *bilibili) GetLiveInfo(id string) (live LiveInfo, err error) {
77+
defer func() {
78+
if recover() != nil {
79+
err = errors.New("fail get data")
80+
}
81+
}()
82+
live = LiveInfo{RoomID: id}
83+
url := "https://api.live.bilibili.com/api/playurl?cid=" + id + "&otype=json&quality=0&platform=web"
84+
tmp, err := httpGet(url)
85+
videoLinkNum := 1
86+
jsonparser.ArrayEach([]byte(tmp), func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
87+
if videoLinkNum == 1 {
88+
live.VideoURL, _ = jsonparser.GetString(value, "url")
89+
fmt.Println("get live url")
90+
}
91+
videoLinkNum++
92+
}, "durl")
93+
if live.VideoURL == "" {
94+
err = errors.New("fail get data")
95+
}
96+
return
97+
}

0 commit comments

Comments
 (0)