/*
customAuthParam
*/
-var (
- VERSION = "2.0.11"
-)
+// var (
+// VERSION = "2.0.11"
+// ) // 不再需要
//允许的清晰度
var AcceptQn = map[int]string{
`,"roomid":` + strconv.Itoa(roomid) +
`,"protover":` + strconv.Itoa(c.Protover) +
`,"platform":"`+ c.Platform +
- `","clientver":"` + c.VERSION +
+ // `","clientver":"` + c.VERSION + //delete at 2021 4 14
`","type":` + strconv.Itoa(c.Type) +
`,"key":"` + key + `"}`
"time"
"os"
"strconv"
- "strings"
+ // "strings"
"context"
"encoding/json"
"net/http"
`WSURL`:[]func()([]string){//弹幕链接
getDanmuInfo,
},
- `VERSION`:[]func()([]string){//客户版本
- Get_Version,
- },
+ // `VERSION`:[]func()([]string){//客户版本 不再需要
+ // Get_Version,
+ // },
`LIVE_BUVID`:[]func()([]string){//LIVE_BUVID
Get_LIVE_BUVID,
},
`WSURL`:func()(bool){//弹幕链接
return len(c.WSURL) != 0
},
- `VERSION`:func()(bool){//客户版本
- return c.VERSION != `2.0.11`
- },
+ // `VERSION`:func()(bool){//客户版本 不再需要
+ // return c.VERSION != `2.0.11`
+ // },
`LIVE_BUVID`:func()(bool){//LIVE_BUVID
return c.LIVE_BUVID
},
return
}
-func Get_Version() (missKey []string) {
- if c.Roomid == 0 {
- missKey = append(missKey, `Roomid`)
- }
- if len(missKey) != 0 {return}
+// func Get_Version() (missKey []string) { 不再需要
+// if c.Roomid == 0 {
+// missKey = append(missKey, `Roomid`)
+// }
+// if len(missKey) != 0 {return}
- Roomid := strconv.Itoa(c.Roomid)
+// Roomid := strconv.Itoa(c.Roomid)
- apilog := apilog.Base_add(`获取客户版本`)
-
- var player_js_url string
- {//获取player_js_url
- r := g.Get(reqf.Rval{
- Url:"https://live.bilibili.com/blanc/" + Roomid,
- })
-
- if r.Err != nil {
- apilog.L(`E: `,r.Err)
- return
- }
-
- r.S2(`<script src=`,`.js`)
- if r.Err != nil {
- apilog.L(`E: `,r.Err)
- return
- }
-
- for _,v := range r.RS {
- tmp := string(v) + `.js`
- if strings.Contains(tmp,`http`) {continue}
- tmp = `https:` + tmp
- if strings.Contains(tmp,`player`) {
- player_js_url = tmp
- break
- }
- }
- if player_js_url == `` {
- apilog.L(`E: `,`no found player js`)
- return
- }
- }
-
- {//获取VERSION
- r := g.Get(reqf.Rval{
- Url:player_js_url,
- })
-
- if r.Err != nil {
- apilog.L(`E: `,r.Err)
- return
- }
-
- r.S(`Bilibili HTML5 Live Player v`,` `,0,0)
- if r.Err != nil {
- apilog.L(`E: `,r.Err)
- return
- }
- c.VERSION = r.RS[0]
- apilog.L(`T: `,"api version", c.VERSION)
- }
- return
-}
+// apilog := apilog.Base_add(`获取客户版本`)
+
+// var player_js_url string
+// {//获取player_js_url
+// r := g.Get(reqf.Rval{
+// Url:"https://live.bilibili.com/blanc/" + Roomid,
+// })
+
+// if r.Err != nil {
+// apilog.L(`E: `,r.Err)
+// return
+// }
+
+// r.S2(`<script src=`,`.js`)
+// if r.Err != nil {
+// apilog.L(`E: `,r.Err)
+// return
+// }
+
+// for _,v := range r.RS {
+// tmp := string(v) + `.js`
+// if strings.Contains(tmp,`http`) {continue}
+// tmp = `https:` + tmp
+// if strings.Contains(tmp,`player`) {
+// player_js_url = tmp
+// break
+// }
+// }
+// if player_js_url == `` {
+// apilog.L(`E: `,`no found player js`)
+// return
+// }
+// }
+
+// {//获取VERSION
+// r := g.Get(reqf.Rval{
+// Url:player_js_url,
+// })
+
+// if r.Err != nil {
+// apilog.L(`E: `,r.Err)
+// return
+// }
+
+// r.S(`Bilibili HTML5 Live Player v`,` `,0,0)
+// if r.Err != nil {
+// apilog.L(`E: `,r.Err)
+// return
+// }
+// c.VERSION = r.RS[0]
+// apilog.L(`T: `,"api version", c.VERSION)
+// }
+// return
+// }
//调用记录
var boot_Get_cookie funcCtrl.FlashFunc//新的替代旧的
Timeout:3,
});err != nil {
wslog.L(`E: `,err)
- //重试时刷新时间
- s.R.Ts = int(p.Sys().GetMTime())
o = Wasm(maxloop-1, uid, s)
return
}
case r :=<- rec_chan:
if r.Id != s.R.Id {break}//或许接收到之前的请求,校验Id字段
return r.S
- case <- time.After(time.Second*time.Duration(3)):
+ case <- time.After(time.Second*time.Duration(1)):
wslog.L(`E: `,`超时!响应>1s,确认保持`,webpath,`开启`)
- //重试时刷新时间
- s.R.Ts = int(p.Sys().GetMTime())
o = Wasm(maxloop-1, uid, s)
return
}
})
s.Handle(map[string]func(http.ResponseWriter,*http.Request){
`/`:func(w http.ResponseWriter,r *http.Request){
+
+ //header
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+
var path string = r.URL.Path[1:]
- if ext := filepath.Ext(path);ext == `` || ext != `.dtmp` || ext != `.flv` {
- http.FileServer(http.Dir(base_dir)).ServeHTTP(w,r)
- } else {
+ if ext := filepath.Ext(path); ext == `.dtmp` {
path = base_dir+path
if !p.Checkfile().IsExist(path) {
cancel := make(chan struct{})
defer close(cancel)
go func() {
- if e := Stream(path,byteC,cancel);e != nil {
- flog.Base_add(`直播Web服务`).L(`T: `,`E: `,e);
+ if err := Stream(path,byteC,cancel);err != nil {
+ flog.Base_add(`直播Web服务`).L(`T: `,err);
return
}
}()
if len(buf) == 0 {break}
if _,err := w.Write(buf);err != nil {
- flog.Base_add(`直播Web服务`).L(`T: `,`E: `,err);
+ flog.Base_add(`直播Web服务`).L(`T: `,err);
break
} else if fastRespon {
fastRespon = false
if flusher, flushSupport := w.(http.Flusher);flushSupport {flusher.Flush()}
}
}
+ } else {
+ http.FileServer(http.Dir(base_dir)).ServeHTTP(w,r)
}
},
`/exit`:func(w http.ResponseWriter,r *http.Request){
"bytes"
"time"
"errors"
- "path/filepath"
c "github.com/qydysky/bili_danmu/CV"
F "github.com/qydysky/bili_danmu/F"
)
func Stream(path string,streamChan chan []byte,cancel chan struct{}) (error) {
- //
- defer flvlog.L(`T: `,`退出`)
+ flvlog.L(`I: `,path)
+ defer flvlog.L(`I: `,`退出`)
//file
f,err := os.OpenFile(path,os.O_RDONLY,0644)
if err != nil {
defer f.Close()
defer close(streamChan)
- living := filepath.Ext(path) == `.dtmp`
- //living stream ,seed to least
- if living {
- //get flv header(9byte) + FirstTagSize(4byte)
- {
- f.Seek(0,0)
- buf := make([]byte, flv_header_size+previou_tag_size)
- if _,err := f.Read(buf);err != nil {return err}
- if !bytes.Contains(buf,flv_header_sign) {return errors.New(`no flv`)}
- streamChan <- buf
- }
+ //init
+ f.Seek(0,0)
- //get tag func
- var getTag = func(f *os.File)(tag byte,offset int64,buf_p *[]byte,data_p *[]byte){
- buf := make([]byte, tag_header_size)
- buf_p = &buf
- if _,err := f.Read(buf);err != nil {tag = eof_tag;return}
- tag = buf[0]
- size := F.Btoi32(append([]byte{0x00},buf[1:4]...),0)
-
- data := make([]byte, size+previou_tag_size)
- data_p = &data
- if _,err := f.Read(data);err != nil {tag = eof_tag;return}
-
- offset,_ = f.Seek(0,1)
- offset -= tag_header_size+int64(size)+previou_tag_size
- return
- }
+ //get flv header(9byte) + FirstTagSize(4byte)
+ {
+ buf := make([]byte, flv_header_size+previou_tag_size)
+ if _,err := f.Read(buf);err != nil {return err}
+ if !bytes.Contains(buf,flv_header_sign) {return errors.New(`no flv`)}
+ streamChan <- buf
+ }
- //get first video and audio tag
- //find last_keyframe_video_offset
- var last_keyframe_video_offset int64
- first_video_tag,first_audio_tag := false,false
- for {
- tag,offset,buf_p,data_p := getTag(f)
- if tag == script_tag {
+ //get tag func
+ var getTag = func(f *os.File)(tag byte,offset int64,buf_p *[]byte,data_p *[]byte){
+ buf := make([]byte, tag_header_size)
+ buf_p = &buf
+ if _,err := f.Read(buf);err != nil {tag = eof_tag;return}
+ tag = buf[0]
+ size := F.Btoi32(append([]byte{0x00},buf[1:4]...),0)
+
+ data := make([]byte, size+previou_tag_size)
+ data_p = &data
+ if _,err := f.Read(data);err != nil {tag = eof_tag;return}
+
+ offset,_ = f.Seek(0,1)
+ offset -= tag_header_size+int64(size)+previou_tag_size
+ return
+ }
+
+ //get first video and audio tag
+ //find last_keyframe_video_offset
+ var last_keyframe_video_offsets []int64
+ first_video_tag,first_audio_tag := false,false
+ for {
+ tag,offset,buf_p,data_p := getTag(f)
+ if tag == script_tag {
+ streamChan <- *buf_p
+ streamChan <- *data_p
+ } else if tag == video_tag {
+ if !first_video_tag {
+ first_video_tag = true
streamChan <- *buf_p
streamChan <- *data_p
- } else if tag == video_tag {
- if !first_video_tag {
- first_video_tag = true
- streamChan <- *buf_p
- streamChan <- *data_p
- }
+ }
- if (*data_p)[0] & 0xf0 == 0x10 {
- last_keyframe_video_offset = offset
- }
- } else if tag == audio_tag {
- if !first_audio_tag {
- first_audio_tag = true
- streamChan <- *buf_p
- streamChan <- *data_p
+ if (*data_p)[0] & 0xf0 == 0x10 {
+ if len(last_keyframe_video_offsets) > 2 {
+ last_keyframe_video_offsets = append(last_keyframe_video_offsets[1:], offset)
+ } else {
+ last_keyframe_video_offsets = append(last_keyframe_video_offsets, offset)
}
- } else {//eof_tag
- break;
}
+ } else if tag == audio_tag {
+ if !first_audio_tag {
+ first_audio_tag = true
+ streamChan <- *buf_p
+ streamChan <- *data_p
+ }
+ } else {//eof_tag
+ break;
}
-
- //seed to last tag
- f.Seek(last_keyframe_video_offset,0)
}
+ //seed to the second last tag
+ f.Seek(last_keyframe_video_offsets[0],0)
+
//copy
{
buf := make([]byte, copy_buf_size)
if err != nil {
preOffset,_ = f.Seek(0,1)
- time.Sleep(time.Duration(3) * time.Second)
+ time.Sleep(time.Duration(1) * time.Second)
}
}
F.Get(`Silver_2_coin`)
//每日签到
F.Dosign()
- //客户版本
- F.Get(`VERSION`)
+ // //客户版本 不再需要
+ // F.Get(`VERSION`)
//附加功能 保持牌子点亮
go reply.Keep_medal_light()
//附加功能 自动发送即将过期礼物
`new day`:func(data interface{})(bool){//日期更换
//每日签到
F.Dosign()
- //获取用户版本
- go F.Get(`VERSION`)
+ // //获取用户版本 不再需要
+ // go F.Get(`VERSION`)
//每日兑换硬币
go F.Silver_2_coin()
//小心心