u
This commit is contained in:
parent
efe39dda4d
commit
104195b977
31
.goreleaser.yaml
Normal file
31
.goreleaser.yaml
Normal file
@ -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
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -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.
|
58
README.md
Normal file
58
README.md
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
```
|
@ -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
|
||||
}
|
||||
|
3
constant/version.go
Normal file
3
constant/version.go
Normal file
@ -0,0 +1,3 @@
|
||||
package constant
|
||||
|
||||
var Version string = "dev"
|
7
main.go
7
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())
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user