mirror of https://github.com/gwuhaolin/livego.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
3.5 KiB
172 lines
3.5 KiB
package main |
|
|
|
import ( |
|
"flag" |
|
"net" |
|
"os" |
|
"os/signal" |
|
"syscall" |
|
"time" |
|
"github.com/gwuhaolin/livego/protocol/rtmp" |
|
"github.com/gwuhaolin/livego/protocol/hls" |
|
"github.com/gwuhaolin/livego/protocol/httpflv" |
|
"github.com/gwuhaolin/livego/protocol/httpopera" |
|
"path/filepath" |
|
"strings" |
|
"io/ioutil" |
|
"strconv" |
|
"log" |
|
) |
|
|
|
var ( |
|
rtmpAddr = flag.String("rtmpAddr", ":1935", "The rtmp server address to bind.") |
|
flvAddr = flag.String("flvAddr", ":8081", "the http-flv server address to bind.") |
|
hlsAddr = flag.String("hlsAddr", ":8080", "the hls server address to bind.") |
|
operaAddr = flag.String("operaAddr", "", "the http operation or config address to bind: 8082.") |
|
CurDir string // save pid |
|
) |
|
|
|
func getParentDirectory(dirctory string) string { |
|
return substr(dirctory, 0, strings.LastIndex(dirctory, "/")) |
|
} |
|
|
|
func getCurrentDirectory() string { |
|
dir, err := filepath.Abs(filepath.Dir(os.Args[0])) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
return strings.Replace(dir, "\\", "/", -1) |
|
} |
|
|
|
func substr(s string, pos, length int) string { |
|
runes := []rune(s) |
|
l := pos + length |
|
if l > len(runes) { |
|
l = len(runes) |
|
} |
|
return string(runes[pos:l]) |
|
} |
|
|
|
func SavePid() error { |
|
pidFilename := CurDir + "/pid/" + filepath.Base(os.Args[0]) + ".pid" |
|
pid := os.Getpid() |
|
return ioutil.WriteFile(pidFilename, []byte(strconv.Itoa(pid)), 0755) |
|
} |
|
|
|
func init() { |
|
CurDir = getParentDirectory(getCurrentDirectory()) |
|
flag.Usage = func() { |
|
flag.PrintDefaults() |
|
} |
|
flag.Parse() |
|
} |
|
|
|
func catchSignal() { |
|
sig := make(chan os.Signal) |
|
signal.Notify(sig, syscall.SIGSTOP, syscall.SIGTERM) |
|
<-sig |
|
log.Println("recieved signal!") |
|
} |
|
|
|
func startHls() *hls.Server { |
|
hlsListen, err := net.Listen("tcp", *hlsAddr) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
|
|
hlsServer := hls.NewServer() |
|
go func() { |
|
defer func() { |
|
if r := recover(); r != nil { |
|
log.Println("hls server panic: ", r) |
|
} |
|
}() |
|
hlsServer.Serve(hlsListen) |
|
}() |
|
return hlsServer |
|
} |
|
|
|
func startRtmp(stream *rtmp.RtmpStream, hlsServer *hls.Server) { |
|
rtmplisten, err := net.Listen("tcp", *rtmpAddr) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
|
|
rtmpServer := rtmp.NewRtmpServer(stream, hlsServer) |
|
go func() { |
|
defer func() { |
|
if r := recover(); r != nil { |
|
log.Println("hls server panic: ", r) |
|
} |
|
}() |
|
rtmpServer.Serve(rtmplisten) |
|
}() |
|
} |
|
|
|
func startHTTPFlv(stream *rtmp.RtmpStream) { |
|
flvListen, err := net.Listen("tcp", *flvAddr) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
|
|
hdlServer := httpflv.NewServer(stream) |
|
go func() { |
|
defer func() { |
|
if r := recover(); r != nil { |
|
log.Println("hls server panic: ", r) |
|
} |
|
}() |
|
hdlServer.Serve(flvListen) |
|
}() |
|
} |
|
|
|
func startHTTPOpera(stream *rtmp.RtmpStream) { |
|
if *operaAddr != "" { |
|
opListen, err := net.Listen("tcp", *operaAddr) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
opServer := httpopera.NewServer(stream) |
|
go func() { |
|
defer func() { |
|
if r := recover(); r != nil { |
|
log.Println("hls server panic: ", r) |
|
} |
|
}() |
|
opServer.Serve(opListen) |
|
}() |
|
} |
|
} |
|
|
|
func startLog() { |
|
log.Println("RTMP Listen On", *rtmpAddr) |
|
log.Println("HLS Listen On", *hlsAddr) |
|
log.Println("HTTP-FLV Listen On", *flvAddr) |
|
if *operaAddr != "" { |
|
log.Println("HTTP-Operation Listen On", *operaAddr) |
|
} |
|
SavePid() |
|
} |
|
|
|
func main() { |
|
defer func() { |
|
if r := recover(); r != nil { |
|
log.Println("main panic: ", r) |
|
time.Sleep(1 * time.Second) |
|
} |
|
}() |
|
|
|
stream := rtmp.NewRtmpStream() |
|
// hls |
|
h := startHls() |
|
// rtmp |
|
startRtmp(stream, h) |
|
// http-flv |
|
startHTTPFlv(stream) |
|
// http-opera |
|
startHTTPOpera(stream) |
|
// my log |
|
startLog() |
|
// block |
|
catchSignal() |
|
}
|
|
|