diff --git a/README.md b/README.md
index 7015afc..20d2f48 100644
--- a/README.md
+++ b/README.md
@@ -67,6 +67,11 @@ Bililive-go是一个支持多种直播平台的直播录制工具,运行在 CL
www.openrec.tv |
滋瓷 |
+
+ | 企鹅电竞 |
+ egame.qq.com |
+ 滋瓷 |
+
## 依赖
diff --git a/src/api/live.go b/src/api/live.go
index cc44d62..d952e87 100755
--- a/src/api/live.go
+++ b/src/api/live.go
@@ -23,6 +23,7 @@ var LivePlatformCNNameMap = map[string]string{
"www.huya.com": "虎牙",
"cc.163.com": "CC直播",
"www.openrec.tv": "openrec",
+ "egame.qq.com": "企鹅电竞",
}
type Info struct {
@@ -99,6 +100,8 @@ func NewLive(url *url.URL) (Live, error) {
live = &CCLive{abstractLive: baseLive}
case "www.openrec.tv":
live = &OpenRecLive{abstractLive: baseLive}
+ case "egame.qq.com":
+ live = &QQLive{abstractLive: baseLive}
default:
live = nil
}
diff --git a/src/api/qq_live.go b/src/api/qq_live.go
new file mode 100644
index 0000000..092aac1
--- /dev/null
+++ b/src/api/qq_live.go
@@ -0,0 +1,74 @@
+package api
+
+import (
+ "errors"
+ "net/url"
+ "regexp"
+ "strings"
+
+ "github.com/tidwall/gjson"
+
+ "github.com/hr3lxphr6j/bililive-go/src/lib/http"
+)
+
+var (
+ qqLiveMobileUrl = "https://m.egame.qq.com/live"
+ qqLiveStreamsReg = regexp.MustCompile(`"urlArray":(\[[^\]]+\])`)
+ qqLiveRoomNameReg = regexp.MustCompile(`title:"([^"]*)"`)
+ qqLiveHostNameReg = regexp.MustCompile(`nickName:"([^"]+)"`)
+ qqLiveIsLiveReg = regexp.MustCompile(`"isLive":(\d+)`)
+)
+
+type QQLive struct {
+ abstractLive
+}
+
+func (q *QQLive) GetInfo() (info *Info, err error) {
+ defer func() {
+ if e := recover(); e != nil {
+ err = e.(error)
+ }
+ }()
+
+ anchorID := strings.Split(q.Url.Path, "/")[1]
+ dom, err := http.Get(q.Url.String(), nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ roomName := qqLiveRoomNameReg.FindSubmatch(dom)[1]
+ hostName := qqLiveHostNameReg.FindSubmatch(dom)[1]
+ dom2, err := http.Get(qqLiveMobileUrl, map[string]string{
+ "anchorid": anchorID,
+ }, nil)
+ isLive := string(qqLiveIsLiveReg.FindSubmatch(dom2)[1]) == "1"
+ info = &Info{
+ Live: q,
+ RoomName: string(roomName),
+ HostName: string(hostName),
+ Status: isLive,
+ }
+ q.cachedInfo = info
+ return info, nil
+}
+
+func (q *QQLive) GetStreamUrls() (us []*url.URL, err error) {
+ defer func() {
+ if e := recover(); e != nil {
+ err = e.(error)
+ }
+ }()
+
+ dom, err := http.Get(q.Url.String(), nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ result := qqLiveStreamsReg.FindSubmatch(dom)
+ if len(result) != 2 {
+ return nil, errors.New("failed to get streams")
+ }
+ u, err := url.Parse(gjson.GetBytes(result[1], "#[bitrate==0].playUrl").String())
+ if err != nil {
+ return nil, err
+ }
+ return []*url.URL{u}, nil
+}
diff --git a/src/api/qq_live_test.go b/src/api/qq_live_test.go
new file mode 100644
index 0000000..a6cf7bb
--- /dev/null
+++ b/src/api/qq_live_test.go
@@ -0,0 +1,22 @@
+package api
+
+import (
+ "net/url"
+ "testing"
+)
+
+const (
+ qqTestUrl = "https://egame.qq.com/497383565"
+)
+
+func TestQQ_GetInfo(t *testing.T) {
+ u, _ := url.Parse(qqTestUrl)
+ live, _ := NewLive(u)
+ t.Log(live.GetInfo())
+}
+
+func TestQQ_GetStreamUrls(t *testing.T) {
+ u, _ := url.Parse(qqTestUrl)
+ live, _ := NewLive(u)
+ t.Log(live.GetStreamUrls())
+}