diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..9bc5fb3 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,31 @@ +project_name: live-streamer +builds: + - env: + - CGO_ENABLED=0 + goos: + - windows + - linux + - darwin + goarch: + - amd64 + - arm64 + - arm + - "386" + ldflags: + - -s -w -X live-streamer/constant.Version={{ .Version }} + flags: + - -trimpath +archives: + - format: tar.gz + format_overrides: + - format: zip + goos: windows + wrap_in_directory: true + files: + - LICENSE + - README.md +release: + draft: true +upx: + - enabled: true + compress: best diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c3ff55b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Nite07 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..192f339 --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +# Liver streamer + +一个基于 Go 语言的自动视频推流工具。 + +## 功能特点 + +- 🎥 支持自动循环推流指定文件夹中的视频文件 +- 🎮 提供 Web 控制面板实时监控推流状态 +- ⚙️ 灵活的视频编码和推流参数配置 +- 🎯 支持视频片段截取推流(指定开始和结束时间) +- 🔄 支持手动切换当前推流视频 + +## 示例配置 + +除了 input 和 output 部分,其余都是可选的 + +```json +{ + "input": [ + "./videos", + { + "path": "./video1.mp4", + "start": "00:01:00", + "end": "01:00:00" + }, + { + "path": "./video2.mkv", + "start": "10s", + "end": "100s" + } + ], + "play": { + "video_codec": "libx264", + "preset": "medium", + "crf": 23, + "max_rate": "1000k", + "buf_size": "2000k", + "scale": "1920:1080", + "frame_rate": 30, + "audio_codec": "aac", + "audio_bitrate": "128k", + "audio_sample_rate": 44100, + "output_format": "flv", + "custom_args": "" + }, + "output": { + "rtmp_server": "rtmp://live-push.example.com/live", + "stream_key": "your-stream-key" + }, + "log": { + "play_state": true + }, + "server": { + "addr": ":8080", + "token": "your-access-token" + } +} +``` diff --git a/config/config.go b/config/config.go index defc0be..bc5c5c5 100644 --- a/config/config.go +++ b/config/config.go @@ -43,7 +43,8 @@ type LogConfig struct { PlayState bool `json:"play_state"` } -type AuthConfig struct { +type ServerConfig struct { + Addr string `json:"addr"` Token string `json:"token"` } @@ -54,7 +55,7 @@ type Config struct { Play PlayConfig `json:"play"` Output OutputConfig `json:"output"` Log LogConfig `json:"log"` - Auth AuthConfig `json:"auth"` + Server ServerConfig `json:"server"` } var GlobalConfig Config @@ -107,6 +108,22 @@ func readConfig(configPath string) error { return nil } +func validateConfig() error { + if err := validateInputConfig(); err != nil { + return err + } + if err := validateOutputConfig(); err != nil { + return err + } + if err := validatePlayConfig(); err != nil { + return err + } + if err := validateServerConfig(); err != nil { + return err + } + return nil +} + func validateInputConfig() error { if GlobalConfig.Input == nil { return errors.New("video_path is nil") @@ -192,15 +209,9 @@ func validatePlayConfig() error { return nil } -func validateConfig() error { - if err := validateInputConfig(); err != nil { - return err - } - if err := validateOutputConfig(); err != nil { - return err - } - if err := validatePlayConfig(); err != nil { - return err +func validateServerConfig() error { + if GlobalConfig.Server.Addr == "" { + GlobalConfig.Server.Addr = ":8080" } return nil } diff --git a/constant/version.go b/constant/version.go new file mode 100644 index 0000000..ac0fecf --- /dev/null +++ b/constant/version.go @@ -0,0 +1,3 @@ +package constant + +var Version string = "dev" diff --git a/main.go b/main.go index 284feca..5d4a6d0 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,9 @@ package main import ( "bufio" "fmt" + "live-streamer/config" + "live-streamer/constant" "live-streamer/server" "live-streamer/streamer" "live-streamer/utils" @@ -17,7 +19,8 @@ import ( var GlobalStreamer *streamer.Streamer func main() { - server.NewServer(":8080", websocket.RequestHandler) + fmt.Println("Version: " + constant.Version) + server.NewServer(config.GlobalConfig.Server.Addr, websocket.RequestHandler) server.GlobalServer.Run() if !utils.HasFFMPEG() { log.Fatal("ffmpeg not found") @@ -32,7 +35,7 @@ func main() { func input() { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { - line := scanner.Text() // 获取用户输入的内容 + line := scanner.Text() switch line { case "list": fmt.Println(GlobalStreamer.GetVideoListPath()) diff --git a/server/server.go b/server/server.go index a04af28..e2b27a8 100644 --- a/server/server.go +++ b/server/server.go @@ -136,8 +136,8 @@ func (s *Server) handleWebSocket(c *gin.Context) { func AuthMiddleware() gin.HandlerFunc { return func(c *gin.Context) { - if config.GlobalConfig.Auth.Token == "" || - c.Query("token") == config.GlobalConfig.Auth.Token { + if config.GlobalConfig.Server.Token == "" || + c.Query("token") == config.GlobalConfig.Server.Token { c.Next() } else { c.AbortWithStatus(http.StatusUnauthorized)