Browse Source

Merge pull request #86 from GNURub/master

JWT for HTTP-Operation API
pull/89/head
浩麟 5 years ago committed by GitHub
parent
commit
2634d2bdb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .gitignore
  2. 44
      CHANGELOG.md
  3. 9
      Dockerfile
  4. 49
      README.md
  5. 0
      config/livego.json
  6. 200
      configure/channel.go
  7. 81
      configure/liveconfig.go
  8. 2
      container/flv/demuxer.go
  9. 18
      container/flv/muxer.go
  10. 2
      container/flv/tag.go
  11. 2
      container/ts/muxer.go
  12. 3
      container/ts/muxer_test.go
  13. 10
      go.mod
  14. 53
      go.sum
  15. 12
      main.go
  16. 2
      parser/aac/parser.go
  17. 8
      parser/parser.go
  18. 5
      protocol/hls/hls.go
  19. 8
      protocol/hls/source.go
  20. 4
      protocol/httpflv/server.go
  21. 8
      protocol/httpflv/writer.go
  22. 229
      protocol/httpopera/http_opera.go
  23. 2
      protocol/rtmp/cache/cache.go
  24. 2
      protocol/rtmp/cache/gop.go
  25. 4
      protocol/rtmp/cache/special.go
  26. 4
      protocol/rtmp/core/chunk_stream.go
  27. 3
      protocol/rtmp/core/chunk_stream_test.go
  28. 4
      protocol/rtmp/core/conn.go
  29. 4
      protocol/rtmp/core/conn_client.go
  30. 4
      protocol/rtmp/core/conn_server.go
  31. 3
      protocol/rtmp/core/conn_test.go
  32. 2
      protocol/rtmp/core/handshake.go
  33. 21
      protocol/rtmp/rtmp.go
  34. 4
      protocol/rtmp/rtmprelay/rtmprelay.go
  35. 8
      protocol/rtmp/rtmprelay/staticrelay.go
  36. 9
      protocol/rtmp/stream.go
  37. 2
      utils/queue/queue.go

4
.gitignore vendored

@ -1,3 +1,7 @@ @@ -1,3 +1,7 @@
# Created by .ignore support plugin (hsz.mobi)
.idea
dist
room_keys.json
.vscode
.tmp
vendor

44
CHANGELOG.md

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- JSON Web Token support.
``` json
// .livego.json
{
"jwt": {
"secret": "testing",
"algorithm": "HS256s"
},
"server": [
{
"appname": "live",
"liveon": "on",
"hlson": "on"
}
]
}
```
- Use redis for store room keys
``` json
// .livego.json
{
"redis_addr": "localhost:6379",
"server": [
{
"appname": "live",
"liveon": "on",
"hlson": "on"
}
]
}
```
### Changed
- Show `players`.
- Show `stream_id`.

9
Dockerfile

@ -3,17 +3,20 @@ WORKDIR /app @@ -3,17 +3,20 @@ WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o livego ./
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o livego .
FROM alpine:latest
LABEL maintainer="gwuhaolin <gwuhaolin@gmail.com>"
LABEL maintainer="Ruben Cid Lara <rubencidlara@gmail.com>"
RUN mkdir -p /app/config
WORKDIR /app
ENV RTMP_PORT 1935
ENV HTTP_FLV_PORT 7001
ENV HLS_PORT 7002
ENV HTTP_OPERATION_PORT 8090
COPY --from=builder /app/config ./config
COPY --from=builder /app/livego .
EXPOSE ${RTMP_PORT}
EXPOSE ${HTTP_FLV_PORT}
EXPOSE ${HLS_PORT}
EXPOSE ${HTTP_OPERATION_PORT}
CMD ./livego
ENTRYPOINT ["./livego"]

49
README.md

@ -1,43 +1,42 @@ @@ -1,43 +1,42 @@
# livego
简单高效的直播服务器:
- 安装和使用非常简单;
- 纯 Golang 编写,性能高,跨平台;
- 支持常用的传输协议、文件格式、编码格式;
Simple and efficient live broadcast server:
- Very simple to install and use;
- Pure Golang, high performance, cross-platform;
- Support commonly used transmission protocols, file formats, encoding formats;
#### 支持的传输协议
#### Supported transport protocols
- RTMP
- AMF
- HLS
- HTTP-FLV
#### 支持的容器格式
#### Supported container formats
- FLV
- TS
#### 支持的编码格式
#### Supported encoding formats
- H264
- AAC
- MP3
- sMP3
## 安装
直接下载编译好的[二进制文件](https://github.com/gwuhaolin/livego/releases)后,在命令行中执行。
## Installation
After directly downloading the compiled [binary file](https://github.com/gwuhaolin/livego/releases), execute it on the command line.
#### 从 Docker 启动
执行`docker run -p 1935:1935 -p 7001:7001 -p 7002:7002 -d --name livego gwuhaolin/livego`启动
#### Boot from Docker
Run `docker run -p 1935:1935 -p 7001:7001 -p 7002:7002 -d --name livego gnurub/livego` to start
#### 从源码编译
1. 下载源码 `git clone https://github.com/gwuhaolin/livego.git`
2. 去 livego 目录中 执行 `go build`
#### Compile from source
1. Download the source code `git clone https://github.com/gwuhaolin/livego.git`
2. Go to the livego directory and execute `go build`
## 使用
2. 启动服务:执行 `livego` 二进制文件启动 livego 服务;
3. 上行推流:通过 `RTMP` 协议把视频流推送到 `rtmp://localhost:1935/live/movie`,例如使用 `ffmpeg -re -i demo.flv -c copy -f flv rtmp://localhost:1935/live/movie` 推送;
4. 下行播放:支持以下三种播放协议,播放地址如下:
- `RTMP`:`rtmp://localhost:1935/live/movie`
- `FLV`:`http://127.0.0.1:7001/live/movie.flv`
- `HLS`:`http://127.0.0.1:7002/live/movie.m3u8`
## Use
2. Start the service: execute the livego binary file to start the livego service;
3. Upstream push: Push the video stream to `rtmp://localhost:1935/live/movie` through the` RTMP` protocol, for example, use `ffmpeg -re -i demo.flv -c copy -f flv rtmp://localhost:1935/live/movie` push;
4. Downstream playback: The following three playback protocols are supported, and the playback address is as follows:
-`RTMP`:`rtmp://localhost:1935/live/movie`
-`FLV`:`http://127.0.0.1:7001/live/movie.flv`
-`HLS`:`http://127.0.0.1:7002/live/movie.m3u8`
### [Use with flv.js](https://github.com/gwuhaolin/blog/issues/3)
### [和 flv.js 搭配使用](https://github.com/gwuhaolin/blog/issues/3)
对Golang感兴趣?请看[Golang 中文学习资料汇总](http://go.wuhaolin.cn/)
Interested in Golang? Please see [Golang Chinese Learning Materials Summary](http://go.wuhaolin.cn/)

0
.livego.json → config/livego.json

200
configure/channel.go

@ -0,0 +1,200 @@ @@ -0,0 +1,200 @@
package configure
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"math/rand"
"sync"
"time"
"github.com/go-redis/redis/v7"
)
var RoomKeys = LoadRoomKey(*GetKeyFile())
var roomUpdated = false
var saveInFile = true
var redisCli *redis.Client
func Init() {
saveInFile = GetRedisAddr() == nil
rand.Seed(time.Now().UnixNano())
if saveInFile {
go func() {
for {
time.Sleep(15 * time.Second)
if roomUpdated {
RoomKeys.Save(*roomKeySaveFile)
roomUpdated = false
}
}
}()
return
}
redisCli = redis.NewClient(&redis.Options{
Addr: *GetRedisAddr(),
Password: *GetRedisPwd(),
DB: 0,
})
_, err := redisCli.Ping().Result()
if err != nil {
panic(err)
}
log.Printf("Redis connected")
}
type RoomKeysType struct {
mapChanKey sync.Map
mapKeyChan sync.Map
}
func LoadRoomKey(f string) *RoomKeysType {
result := &RoomKeysType{
mapChanKey: sync.Map{},
mapKeyChan: sync.Map{},
}
raw := map[string]string{}
content, err := ioutil.ReadFile(f)
if err != nil {
log.Printf("Failed to read file %s for room keys", f)
return result
}
if json.Unmarshal(content, &raw) != nil {
log.Printf("Failed to unmarshal file %s for room keys", f)
return result
}
for room, key := range raw {
result.mapChanKey.Store(room, key)
result.mapKeyChan.Store(key, room)
}
return result
}
func (r *RoomKeysType) Save(f string) {
raw := map[string]string{}
r.mapChanKey.Range(func(channel, key interface{}) bool {
raw[channel.(string)] = key.(string)
return true
})
content, err := json.Marshal(raw)
if err != nil {
log.Println("Failed to marshal room keys")
return
}
if ioutil.WriteFile(f, content, 0644) != nil {
log.Println("Failed to save room keys")
return
}
}
// set/reset a random key for channel
func (r *RoomKeysType) SetKey(channel string) (key string, err error) {
if !saveInFile {
for {
key = randStringRunes(48)
if _, err = redisCli.Get(key).Result(); err == redis.Nil {
err = redisCli.Set(channel, key, 0).Err()
if err != nil {
return
}
err = redisCli.Set(key, channel, 0).Err()
return
} else if err != nil {
return
}
}
}
for {
key = randStringRunes(48)
if _, found := r.mapKeyChan.Load(key); !found {
r.mapChanKey.Store(channel, key)
r.mapKeyChan.Store(key, channel)
break
}
}
roomUpdated = true
return
}
func (r *RoomKeysType) GetKey(channel string) (newKey string, err error) {
if !saveInFile {
if newKey, err = redisCli.Get(channel).Result(); err == redis.Nil {
newKey, err = r.SetKey(channel)
log.Printf("[KEY] new channel [%s]: %s", channel, newKey)
return
}
return
}
var key interface{}
var found bool
if key, found = r.mapChanKey.Load(channel); found {
return key.(string), nil
}
newKey, err = r.SetKey(channel)
log.Printf("[KEY] new channel [%s]: %s", channel, newKey)
return
}
func (r *RoomKeysType) GetChannel(key string) (channel string, err error) {
if !saveInFile {
return redisCli.Get(key).Result()
}
chann, found := r.mapKeyChan.Load(key)
if found {
return chann.(string), nil
} else {
return "", fmt.Errorf("%s does not exists", key)
}
}
func (r *RoomKeysType) DeleteChannel(channel string) bool {
if !saveInFile {
return redisCli.Del(channel).Err() != nil
}
key, ok := r.mapChanKey.Load(channel)
if ok {
r.mapChanKey.Delete(channel)
r.mapKeyChan.Delete(key)
return true
}
return false
}
func (r *RoomKeysType) DeleteKey(key string) bool {
if !saveInFile {
return redisCli.Del(key).Err() != nil
}
channel, ok := r.mapKeyChan.Load(key)
if ok {
r.mapChanKey.Delete(channel)
r.mapKeyChan.Delete(key)
return true
}
return false
}
// helpers
var letterRunes = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func randStringRunes(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}

81
configure/liveconfig.go

@ -2,44 +2,60 @@ package configure @@ -2,44 +2,60 @@ package configure
import (
"encoding/json"
"flag"
"io/ioutil"
"log"
)
/*
{
[
{
"application":"live",
"live":"on",
"hls":"on",
"static_push":["rtmp://xx/live"]
}
]
"server": [
{
"appname": "live",
"liveon": "on",
"hlson": "on",
"static_push": []
}
]
}
*/
var (
roomKeySaveFile = flag.String("KeyFile", "room_keys.json", "path to save room keys")
RedisAddr = flag.String("redis_addr", "", "redis addr to save room keys ex. localhost:6379")
RedisPwd = flag.String("redis_pwd", "", "redis password")
)
type Application struct {
Appname string
Liveon string
Hlson string
Static_push []string
Appname string `json:"appname"`
Liveon string `json:"liveon"`
Hlson string `json:"hlson"`
StaticPush []string `json:"static_push"`
}
type JWTCfg struct {
Secret string `json:"secret"`
Algorithm string `json:"algorithm"`
}
type ServerCfg struct {
Server []Application
KeyFile string `json:"key_file"`
RedisAddr string `json:"redis_addr"`
RedisPwd string `json:"redis_pwd"`
JWTCfg `json:"jwt"`
Server []Application `json:"server"`
}
var RtmpServercfg ServerCfg
func LoadConfig(configfilename string) error {
log.Printf("starting load configure file(%s)......", configfilename)
log.Printf("starting load configure file %s", configfilename)
data, err := ioutil.ReadFile(configfilename)
if err != nil {
log.Printf("ReadFile %s error:%v", configfilename, err)
return err
}
log.Printf("loadconfig: \r\n%s", string(data))
// log.Printf("loadconfig: \r\n%s", string(data))
err = json.Unmarshal(data, &RtmpServercfg)
if err != nil {
@ -47,9 +63,40 @@ func LoadConfig(configfilename string) error { @@ -47,9 +63,40 @@ func LoadConfig(configfilename string) error {
return err
}
log.Printf("get config json data:%v", RtmpServercfg)
Init()
return nil
}
func GetKeyFile() *string {
if len(RtmpServercfg.KeyFile) > 0 {
*roomKeySaveFile = RtmpServercfg.KeyFile
}
return roomKeySaveFile
}
func GetRedisAddr() *string {
if len(RtmpServercfg.RedisAddr) > 0 {
*RedisAddr = RtmpServercfg.RedisAddr
}
if len(*RedisAddr) == 0 {
return nil
}
return RedisAddr
}
func GetRedisPwd() *string {
if len(RtmpServercfg.RedisPwd) > 0 {
*RedisPwd = RtmpServercfg.RedisPwd
}
return RedisPwd
}
func CheckAppName(appname string) bool {
for _, app := range RtmpServercfg.Server {
if (app.Appname == appname) && (app.Liveon == "on") {
@ -62,8 +109,8 @@ func CheckAppName(appname string) bool { @@ -62,8 +109,8 @@ func CheckAppName(appname string) bool {
func GetStaticPushUrlList(appname string) ([]string, bool) {
for _, app := range RtmpServercfg.Server {
if (app.Appname == appname) && (app.Liveon == "on") {
if len(app.Static_push) > 0 {
return app.Static_push, true
if len(app.StaticPush) > 0 {
return app.StaticPush, true
} else {
return nil, false
}

2
container/flv/demuxer.go

@ -3,7 +3,7 @@ package flv @@ -3,7 +3,7 @@ package flv
import (
"errors"
"github.com/gwuhaolin/livego/av"
"livego/av"
)
var (

18
container/flv/muxer.go

@ -5,20 +5,22 @@ import ( @@ -5,20 +5,22 @@ import (
"fmt"
"log"
"os"
"path"
"strings"
"time"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/protocol/amf"
"github.com/gwuhaolin/livego/utils/pio"
"github.com/gwuhaolin/livego/utils/uid"
"livego/av"
"livego/protocol/amf"
"livego/utils/pio"
"livego/utils/uid"
)
var (
flvHeader = []byte{0x46, 0x4c, 0x56, 0x01, 0x05, 0x00, 0x00, 0x00, 0x09}
flvFile = flag.String("filFile", "./out.flv", "output flv file name")
flvDir = flag.String("flvDir", "tmp", "output flv file at flvDir/APP/KEY_TIME.flv")
)
/*
func NewFlv(handler av.Handler, info av.Info) {
patths := strings.SplitN(info.Key, "/", 2)
@ -41,6 +43,7 @@ func NewFlv(handler av.Handler, info av.Info) { @@ -41,6 +43,7 @@ func NewFlv(handler av.Handler, info av.Info) {
log.Println("close flv file")
writer.ctx.Close()
}
*/
const (
headerLen = 11
@ -144,18 +147,17 @@ type FlvDvr struct{} @@ -144,18 +147,17 @@ type FlvDvr struct{}
func (f *FlvDvr) GetWriter(info av.Info) av.WriteCloser {
paths := strings.SplitN(info.Key, "/", 2)
if len(paths) != 2 {
log.Println("invalid info")
return nil
}
err := os.MkdirAll(paths[0], 0755)
err := os.MkdirAll(path.Join(*flvDir, paths[0]), 0755)
if err != nil {
log.Println("mkdir error:", err)
return nil
}
fileName := fmt.Sprintf("%s_%d.%s", info.Key, time.Now().Unix(), "flv")
fileName := fmt.Sprintf("%s_%d.%s", path.Join(*flvDir, info.Key), time.Now().Unix(), "flv")
log.Println("flv dvr save stream to: ", fileName)
w, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR, 0755)
if err != nil {

2
container/flv/tag.go

@ -3,7 +3,7 @@ package flv @@ -3,7 +3,7 @@ package flv
import (
"fmt"
"github.com/gwuhaolin/livego/av"
"livego/av"
)
type flvTag struct {

2
container/ts/muxer.go

@ -3,7 +3,7 @@ package ts @@ -3,7 +3,7 @@ package ts
import (
"io"
"github.com/gwuhaolin/livego/av"
"livego/av"
)
const (

3
container/ts/muxer_test.go

@ -3,7 +3,8 @@ package ts @@ -3,7 +3,8 @@ package ts
import (
"testing"
"github.com/gwuhaolin/livego/av"
"livego/av"
"github.com/stretchr/testify/assert"
)

10
go.mod

@ -1,11 +1,15 @@ @@ -1,11 +1,15 @@
module github.com/gwuhaolin/livego
module livego
go 1.13
require (
github.com/kr/pretty v0.1.0 // indirect
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/go-redis/redis/v7 v7.2.0
github.com/gorilla/mux v1.7.4 // indirect
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6
github.com/satori/go.uuid v1.2.0
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/stretchr/testify v1.4.0
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
github.com/urfave/negroni v1.0.0 // indirect
)

53
go.sum

@ -1,21 +1,72 @@ @@ -1,21 +1,72 @@
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b h1:CvoEHGmxWl5kONC5icxwqV899dkf4VjOScbxLpllEnw=
github.com/auth0/go-jwt-middleware v0.0.0-20190805220309-36081240882b/go.mod h1:LWMyo4iOLWXHGdBki7NIht1kHru/0wM179h+d3g8ATM=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-redis/redis/v7 v7.2.0 h1:CrCexy/jYWZjW0AyVoHlcJUeZN19VWlbepTh1Vq6dJs=
github.com/go-redis/redis/v7 v7.2.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6 h1:lNCW6THrCKBiJBpz8kbVGjC7MgdCGKwuvBgc7LoD6sw=
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

12
main.go

@ -6,11 +6,11 @@ import ( @@ -6,11 +6,11 @@ import (
"net"
"time"
"github.com/gwuhaolin/livego/configure"
"github.com/gwuhaolin/livego/protocol/hls"
"github.com/gwuhaolin/livego/protocol/httpflv"
"github.com/gwuhaolin/livego/protocol/httpopera"
"github.com/gwuhaolin/livego/protocol/rtmp"
"livego/configure"
"livego/protocol/hls"
"livego/protocol/httpflv"
"livego/protocol/httpopera"
"livego/protocol/rtmp"
)
var (
@ -19,7 +19,7 @@ var ( @@ -19,7 +19,7 @@ var (
httpFlvAddr = flag.String("httpflv-addr", ":7001", "HTTP-FLV server listen address")
hlsAddr = flag.String("hls-addr", ":7002", "HLS server listen address")
operaAddr = flag.String("manage-addr", ":8090", "HTTP manage interface server listen address")
configfilename = flag.String("cfgfile", ".livego.json", "configure filename")
configfilename = flag.String("config-file", "config/livego.json", "configure filename")
)
func init() {

2
parser/aac/parser.go

@ -4,7 +4,7 @@ import ( @@ -4,7 +4,7 @@ import (
"errors"
"io"
"github.com/gwuhaolin/livego/av"
"livego/av"
)
type mpegExtension struct {

8
parser/parser.go

@ -4,10 +4,10 @@ import ( @@ -4,10 +4,10 @@ import (
"errors"
"io"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/parser/aac"
"github.com/gwuhaolin/livego/parser/h264"
"github.com/gwuhaolin/livego/parser/mp3"
"livego/av"
"livego/parser/aac"
"livego/parser/h264"
"livego/parser/mp3"
)
var (

5
protocol/hls/hls.go

@ -11,8 +11,9 @@ import ( @@ -11,8 +11,9 @@ import (
"strings"
"time"
"github.com/gwuhaolin/livego/av"
"github.com/orcaman/concurrent-map"
"livego/av"
cmap "github.com/orcaman/concurrent-map"
)
const (

8
protocol/hls/source.go

@ -7,10 +7,10 @@ import ( @@ -7,10 +7,10 @@ import (
"log"
"time"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/container/flv"
"github.com/gwuhaolin/livego/container/ts"
"github.com/gwuhaolin/livego/parser"
"livego/av"
"livego/container/flv"
"livego/container/ts"
"livego/parser"
)
const (

4
protocol/httpflv/server.go

@ -7,8 +7,8 @@ import ( @@ -7,8 +7,8 @@ import (
"net/http"
"strings"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/protocol/rtmp"
"livego/av"
"livego/protocol/rtmp"
)
type Server struct {

8
protocol/httpflv/writer.go

@ -7,10 +7,10 @@ import ( @@ -7,10 +7,10 @@ import (
"net/http"
"time"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/protocol/amf"
"github.com/gwuhaolin/livego/utils/pio"
"github.com/gwuhaolin/livego/utils/uid"
"livego/av"
"livego/protocol/amf"
"livego/utils/pio"
"livego/utils/uid"
)
const (

229
protocol/httpopera/http_opera.go

@ -3,25 +3,29 @@ package httpopera @@ -3,25 +3,29 @@ package httpopera
import (
"encoding/json"
"fmt"
"io"
"log"
"net"
"net/http"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/protocol/rtmp"
"github.com/gwuhaolin/livego/protocol/rtmp/rtmprelay"
"livego/av"
"livego/configure"
"livego/protocol/rtmp"
"livego/protocol/rtmp/rtmprelay"
jwtmiddleware "github.com/auth0/go-jwt-middleware"
"github.com/dgrijalva/jwt-go"
)
type Response struct {
w http.ResponseWriter
Status int `json:"status"`
Message string `json:"message"`
w http.ResponseWriter
Status int `json:"status"`
Data interface{} `json:"data"`
}
func (r *Response) SendJson() (int, error) {
resp, _ := json.Marshal(r)
r.w.Header().Set("Content-Type", "application/json")
r.w.WriteHeader(r.Status)
return r.w.Write(resp)
}
@ -58,10 +62,38 @@ func NewServer(h av.Handler, rtmpAddr string) *Server { @@ -58,10 +62,38 @@ func NewServer(h av.Handler, rtmpAddr string) *Server {
}
}
func JWTMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if len(configure.RtmpServercfg.JWTCfg.Secret) > 0 {
var algorithm jwt.SigningMethod
if len(configure.RtmpServercfg.JWTCfg.Algorithm) > 0 {
algorithm = jwt.GetSigningMethod(configure.RtmpServercfg.JWTCfg.Algorithm)
}
if algorithm == nil {
algorithm = jwt.SigningMethodHS256
}
jwtMiddleware := jwtmiddleware.New(jwtmiddleware.Options{
Extractor: jwtmiddleware.FromFirst(jwtmiddleware.FromAuthHeader, jwtmiddleware.FromParameter("jwt")),
ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
return []byte(configure.RtmpServercfg.Secret), nil
},
SigningMethod: algorithm,
})
jwtMiddleware.HandlerWithNext(w, r, next.ServeHTTP)
return
}
next.ServeHTTP(w, r)
})
}
func (s *Server) Serve(l net.Listener) error {
mux := http.NewServeMux()
mux.Handle("/statics", http.FileServer(http.Dir("statics")))
mux.Handle("/statics/", http.StripPrefix("/statics/", http.FileServer(http.Dir("statics"))))
mux.HandleFunc("/control/push", func(w http.ResponseWriter, r *http.Request) {
s.handlePush(w, r)
@ -69,21 +101,30 @@ func (s *Server) Serve(l net.Listener) error { @@ -69,21 +101,30 @@ func (s *Server) Serve(l net.Listener) error {
mux.HandleFunc("/control/pull", func(w http.ResponseWriter, r *http.Request) {
s.handlePull(w, r)
})
mux.HandleFunc("/control/get", func(w http.ResponseWriter, r *http.Request) {
s.handleGet(w, r)
})
mux.HandleFunc("/control/reset", func(w http.ResponseWriter, r *http.Request) {
s.handleReset(w, r)
})
mux.HandleFunc("/control/delete", func(w http.ResponseWriter, r *http.Request) {
s.handleDelete(w, r)
})
mux.HandleFunc("/stat/livestat", func(w http.ResponseWriter, r *http.Request) {
s.GetLiveStatics(w, r)
})
http.Serve(l, mux)
http.Serve(l, JWTMiddleware(mux))
return nil
}
type stream struct {
Key string `json:"key"`
Url string `json:"Url"`
StreamId uint32 `json:"StreamId"`
VideoTotalBytes uint64 `json:123456`
VideoSpeed uint64 `json:123456`
AudioTotalBytes uint64 `json:123456`
AudioSpeed uint64 `json:123456`
Url string `json:"url"`
StreamId uint32 `json:"stream_id"`
VideoTotalBytes uint64 `json:"video_total_bytes"`
VideoSpeed uint64 `json:"video_speed"`
AudioTotalBytes uint64 `json:"audio_total_bytes"`
AudioSpeed uint64 `json:"audio_speed"`
}
type streams struct {
@ -93,9 +134,18 @@ type streams struct { @@ -93,9 +134,18 @@ type streams struct {
//http://127.0.0.1:8090/stat/livestat
func (server *Server) GetLiveStatics(w http.ResponseWriter, req *http.Request) {
res := &Response{
w: w,
Data: nil,
Status: 200,
}
defer res.SendJson()
rtmpStream := server.handler.(*rtmp.RtmpStream)
if rtmpStream == nil {
io.WriteString(w, "<h1>Get rtmp stream information error</h1>")
res.Status = 500
res.Data = "Get rtmp stream information error"
return
}
@ -130,17 +180,29 @@ func (server *Server) GetLiveStatics(w http.ResponseWriter, req *http.Request) { @@ -130,17 +180,29 @@ func (server *Server) GetLiveStatics(w http.ResponseWriter, req *http.Request) {
}
}
}
resp, _ := json.Marshal(msgs)
w.Header().Set("Content-Type", "application/json")
w.Write(resp)
res.Data = resp
}
//http://127.0.0.1:8090/control/push?&oper=start&app=live&name=123456&url=rtmp://192.168.16.136/live/123456
//http://127.0.0.1:8090/control/pull?&oper=start&app=live&name=123456&url=rtmp://192.168.16.136/live/123456
func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
var retString string
var err error
req.ParseForm()
res := &Response{
w: w,
Data: nil,
Status: 200,
}
defer res.SendJson()
if req.ParseForm() != nil {
res.Status = 400
res.Data = "url: /control/pull?&oper=start&app=live&name=123456&url=rtmp://192.168.16.136/live/123456"
return
}
oper := req.Form["oper"]
app := req.Form["app"]
@ -149,7 +211,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) { @@ -149,7 +211,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
log.Printf("control pull: oper=%v, app=%v, name=%v, url=%v", oper, app, name, url)
if (len(app) <= 0) || (len(name) <= 0) || (len(url) <= 0) {
io.WriteString(w, "control push parameter error, please check them.</br>")
res.Status = 400
res.Data = "control push parameter error, please check them."
return
}
@ -162,7 +225,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) { @@ -162,7 +225,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
if !found {
retString = fmt.Sprintf("session key[%s] not exist, please check it again.", keyString)
io.WriteString(w, retString)
res.Status = 400
res.Data = retString
return
}
log.Printf("rtmprelay stop push %s from %s", remoteurl, localurl)
@ -170,7 +234,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) { @@ -170,7 +234,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
delete(s.session, keyString)
retString = fmt.Sprintf("<h1>push url stop %s ok</h1></br>", url[0])
io.WriteString(w, retString)
res.Status = 400
res.Data = retString
log.Printf("pull stop return %s", retString)
} else {
pullRtmprelay := rtmprelay.NewRtmpRelay(&localurl, &remoteurl)
@ -182,7 +247,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) { @@ -182,7 +247,8 @@ func (s *Server) handlePull(w http.ResponseWriter, req *http.Request) {
s.session[keyString] = pullRtmprelay
retString = fmt.Sprintf("<h1>push url start %s ok</h1></br>", url[0])
}
io.WriteString(w, retString)
res.Status = 400
res.Data = retString
log.Printf("pull start return %s", retString)
}
}
@ -192,7 +258,18 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) { @@ -192,7 +258,18 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
var retString string
var err error
req.ParseForm()
res := &Response{
w: w,
Data: nil,
Status: 200,
}
defer res.SendJson()
if req.ParseForm() != nil {
res.Data = "url: /control/push?&oper=start&app=live&name=123456&url=rtmp://192.168.16.136/live/123456"
return
}
oper := req.Form["oper"]
app := req.Form["app"]
@ -201,7 +278,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) { @@ -201,7 +278,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
log.Printf("control push: oper=%v, app=%v, name=%v, url=%v", oper, app, name, url)
if (len(app) <= 0) || (len(name) <= 0) || (len(url) <= 0) {
io.WriteString(w, "control push parameter error, please check them.</br>")
res.Data = "control push parameter error, please check them."
return
}
@ -213,7 +290,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) { @@ -213,7 +290,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
pushRtmprelay, found := s.session[keyString]
if !found {
retString = fmt.Sprintf("<h1>session key[%s] not exist, please check it again.</h1>", keyString)
io.WriteString(w, retString)
res.Data = retString
return
}
log.Printf("rtmprelay stop push %s from %s", remoteurl, localurl)
@ -221,7 +298,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) { @@ -221,7 +298,7 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
delete(s.session, keyString)
retString = fmt.Sprintf("<h1>push url stop %s ok</h1></br>", url[0])
io.WriteString(w, retString)
res.Data = retString
log.Printf("push stop return %s", retString)
} else {
pushRtmprelay := rtmprelay.NewRtmpRelay(&localurl, &remoteurl)
@ -234,7 +311,101 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) { @@ -234,7 +311,101 @@ func (s *Server) handlePush(w http.ResponseWriter, req *http.Request) {
s.session[keyString] = pushRtmprelay
}
io.WriteString(w, retString)
res.Data = retString
log.Printf("push start return %s", retString)
}
}
//http://127.0.0.1:8090/control/reset?room=ROOM_NAME
func (s *Server) handleReset(w http.ResponseWriter, r *http.Request) {
res := &Response{
w: w,
Data: nil,
Status: 200,
}
defer res.SendJson()
if err := r.ParseForm(); err != nil {
res.Status = 400
res.Data = "url: /control/reset?room=ROOM_NAME"
return
}
room := r.Form.Get("room")
if len(room) == 0 {
res.Status = 400
res.Data = "url: /control/get?room=ROOM_NAME"
return
}
msg, err := configure.RoomKeys.SetKey(room)
if err != nil {
msg = err.Error()
res.Status = 400
}
res.Data = msg
}
//http://127.0.0.1:8090/control/get?room=ROOM_NAME
func (s *Server) handleGet(w http.ResponseWriter, r *http.Request) {
res := &Response{
w: w,
Data: nil,
Status: 200,
}
defer res.SendJson()
if err := r.ParseForm(); err != nil {
res.Status = 400
res.Data = "url: /control/get?room=ROOM_NAME"
return
}
room := r.Form.Get("room")
if len(room) == 0 {
res.Status = 400
res.Data = "url: /control/get?room=ROOM_NAME"
return
}
msg, err := configure.RoomKeys.GetKey(room)
if err != nil {
msg = err.Error()
res.Status = 400
}
res.Data = msg
}
//http://127.0.0.1:8090/control/delete?room=ROOM_NAME
func (s *Server) handleDelete(w http.ResponseWriter, r *http.Request) {
res := &Response{
w: w,
Data: nil,
Status: 200,
}
defer res.SendJson()
if err := r.ParseForm(); err != nil {
res.Status = 400
res.Data = "url: /control/delete?room=ROOM_NAME"
return
}
room := r.Form.Get("room")
if len(room) == 0 {
res.Status = 400
res.Data = "url: /control/get?room=ROOM_NAME"
return
}
if configure.RoomKeys.DeleteChannel(room) {
res.Data = "Ok"
return
}
res.Status = 404
res.Data = "Room not found"
}

2
protocol/rtmp/cache/cache.go vendored

@ -3,7 +3,7 @@ package cache @@ -3,7 +3,7 @@ package cache
import (
"flag"
"github.com/gwuhaolin/livego/av"
"livego/av"
)
var (

2
protocol/rtmp/cache/gop.go vendored

@ -3,7 +3,7 @@ package cache @@ -3,7 +3,7 @@ package cache
import (
"errors"
"github.com/gwuhaolin/livego/av"
"livego/av"
)
var (

4
protocol/rtmp/cache/special.go vendored

@ -4,8 +4,8 @@ import ( @@ -4,8 +4,8 @@ import (
"bytes"
"log"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/protocol/amf"
"livego/av"
"livego/protocol/amf"
)
const (

4
protocol/rtmp/core/chunk_stream.go

@ -4,8 +4,8 @@ import ( @@ -4,8 +4,8 @@ import (
"encoding/binary"
"fmt"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/utils/pool"
"livego/av"
"livego/utils/pool"
)
type ChunkStream struct {

3
protocol/rtmp/core/chunk_stream_test.go

@ -4,7 +4,8 @@ import ( @@ -4,7 +4,8 @@ import (
"bytes"
"testing"
"github.com/gwuhaolin/livego/utils/pool"
"livego/utils/pool"
"github.com/stretchr/testify/assert"
)

4
protocol/rtmp/core/conn.go

@ -5,8 +5,8 @@ import ( @@ -5,8 +5,8 @@ import (
"net"
"time"
"github.com/gwuhaolin/livego/utils/pio"
"github.com/gwuhaolin/livego/utils/pool"
"livego/utils/pio"
"livego/utils/pool"
)
const (

4
protocol/rtmp/core/conn_client.go

@ -12,8 +12,8 @@ import ( @@ -12,8 +12,8 @@ import (
"log"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/protocol/amf"
"livego/av"
"livego/protocol/amf"
)
var (

4
protocol/rtmp/core/conn_server.go

@ -7,8 +7,8 @@ import ( @@ -7,8 +7,8 @@ import (
"log"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/protocol/amf"
"livego/av"
"livego/protocol/amf"
)
var (

3
protocol/rtmp/core/conn_test.go

@ -5,7 +5,8 @@ import ( @@ -5,7 +5,8 @@ import (
"io"
"testing"
"github.com/gwuhaolin/livego/utils/pool"
"livego/utils/pool"
"github.com/stretchr/testify/assert"
)

2
protocol/rtmp/core/handshake.go

@ -10,7 +10,7 @@ import ( @@ -10,7 +10,7 @@ import (
"time"
"github.com/gwuhaolin/livego/utils/pio"
"livego/utils/pio"
)
var (

21
protocol/rtmp/rtmp.go

@ -11,11 +11,12 @@ import ( @@ -11,11 +11,12 @@ import (
"strings"
"time"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/configure"
"github.com/gwuhaolin/livego/container/flv"
"github.com/gwuhaolin/livego/protocol/rtmp/core"
"github.com/gwuhaolin/livego/utils/uid"
"livego/utils/uid"
"livego/av"
"livego/configure"
"livego/container/flv"
"livego/protocol/rtmp/core"
)
const (
@ -111,7 +112,7 @@ func (s *Server) handleConn(conn *core.Conn) error { @@ -111,7 +112,7 @@ func (s *Server) handleConn(conn *core.Conn) error {
return err
}
appname, _, _ := connServer.GetInfo()
appname, name, _ := connServer.GetInfo()
if ret := configure.CheckAppName(appname); !ret {
err := errors.New(fmt.Sprintf("application name=%s is not configured", appname))
@ -122,6 +123,14 @@ func (s *Server) handleConn(conn *core.Conn) error { @@ -122,6 +123,14 @@ func (s *Server) handleConn(conn *core.Conn) error {
log.Printf("handleConn: IsPublisher=%v", connServer.IsPublisher())
if connServer.IsPublisher() {
channel, err := configure.RoomKeys.GetChannel(name)
if err != nil {
err := errors.New(fmt.Sprintf("invalid key"))
conn.Close()
log.Println("CheckKey err:", err)
return err
}
connServer.PublishInfo.Name = channel
if pushlist, ret := configure.GetStaticPushUrlList(appname); ret && (pushlist != nil) {
log.Printf("GetStaticPushUrlList: %v", pushlist)
}

4
protocol/rtmp/rtmprelay/rtmprelay.go

@ -7,8 +7,8 @@ import ( @@ -7,8 +7,8 @@ import (
"io"
"log"
"github.com/gwuhaolin/livego/protocol/amf"
"github.com/gwuhaolin/livego/protocol/rtmp/core"
"livego/protocol/amf"
"livego/protocol/rtmp/core"
)
var (

8
protocol/rtmp/rtmprelay/staticrelay.go

@ -6,9 +6,9 @@ import ( @@ -6,9 +6,9 @@ import (
"log"
"sync"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/configure"
"github.com/gwuhaolin/livego/protocol/rtmp/core"
"livego/av"
"livego/configure"
"livego/protocol/rtmp/core"
)
type StaticPush struct {
@ -63,7 +63,7 @@ func GetStaticPushObject(rtmpurl string) (*StaticPush, error) { @@ -63,7 +63,7 @@ func GetStaticPushObject(rtmpurl string) (*StaticPush, error) {
}
g_MapLock.RUnlock()
return nil, errors.New(fmt.Sprintf("G_StaticPushMap[%s] not exist...."))
return nil, errors.New(fmt.Sprintf("G_StaticPushMap[%s] not exist....", rtmpurl))
}
func ReleaseStaticPushObject(rtmpurl string) {

9
protocol/rtmp/stream.go

@ -6,10 +6,11 @@ import ( @@ -6,10 +6,11 @@ import (
"strings"
"time"
"github.com/gwuhaolin/livego/av"
"github.com/gwuhaolin/livego/protocol/rtmp/cache"
"github.com/gwuhaolin/livego/protocol/rtmp/rtmprelay"
"github.com/orcaman/concurrent-map"
"livego/av"
"livego/protocol/rtmp/cache"
"livego/protocol/rtmp/rtmprelay"
cmap "github.com/orcaman/concurrent-map"
)
var (

2
utils/queue/queue.go

@ -3,7 +3,7 @@ package queue @@ -3,7 +3,7 @@ package queue
import (
"sync"
"github.com/gwuhaolin/livego/av"
"livego/av"
)
// Queue is a basic FIFO queue for Messages.

Loading…
Cancel
Save