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"`
|
PlayState bool `json:"play_state"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthConfig struct {
|
type ServerConfig struct {
|
||||||
|
Addr string `json:"addr"`
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ type Config struct {
|
|||||||
Play PlayConfig `json:"play"`
|
Play PlayConfig `json:"play"`
|
||||||
Output OutputConfig `json:"output"`
|
Output OutputConfig `json:"output"`
|
||||||
Log LogConfig `json:"log"`
|
Log LogConfig `json:"log"`
|
||||||
Auth AuthConfig `json:"auth"`
|
Server ServerConfig `json:"server"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var GlobalConfig Config
|
var GlobalConfig Config
|
||||||
@ -107,6 +108,22 @@ func readConfig(configPath string) error {
|
|||||||
return nil
|
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 {
|
func validateInputConfig() error {
|
||||||
if GlobalConfig.Input == nil {
|
if GlobalConfig.Input == nil {
|
||||||
return errors.New("video_path is nil")
|
return errors.New("video_path is nil")
|
||||||
@ -192,15 +209,9 @@ func validatePlayConfig() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateConfig() error {
|
func validateServerConfig() error {
|
||||||
if err := validateInputConfig(); err != nil {
|
if GlobalConfig.Server.Addr == "" {
|
||||||
return err
|
GlobalConfig.Server.Addr = ":8080"
|
||||||
}
|
|
||||||
if err := validateOutputConfig(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := validatePlayConfig(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
return nil
|
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 (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"live-streamer/config"
|
"live-streamer/config"
|
||||||
|
"live-streamer/constant"
|
||||||
"live-streamer/server"
|
"live-streamer/server"
|
||||||
"live-streamer/streamer"
|
"live-streamer/streamer"
|
||||||
"live-streamer/utils"
|
"live-streamer/utils"
|
||||||
@ -17,7 +19,8 @@ import (
|
|||||||
var GlobalStreamer *streamer.Streamer
|
var GlobalStreamer *streamer.Streamer
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
server.NewServer(":8080", websocket.RequestHandler)
|
fmt.Println("Version: " + constant.Version)
|
||||||
|
server.NewServer(config.GlobalConfig.Server.Addr, websocket.RequestHandler)
|
||||||
server.GlobalServer.Run()
|
server.GlobalServer.Run()
|
||||||
if !utils.HasFFMPEG() {
|
if !utils.HasFFMPEG() {
|
||||||
log.Fatal("ffmpeg not found")
|
log.Fatal("ffmpeg not found")
|
||||||
@ -32,7 +35,7 @@ func main() {
|
|||||||
func input() {
|
func input() {
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text() // 获取用户输入的内容
|
line := scanner.Text()
|
||||||
switch line {
|
switch line {
|
||||||
case "list":
|
case "list":
|
||||||
fmt.Println(GlobalStreamer.GetVideoListPath())
|
fmt.Println(GlobalStreamer.GetVideoListPath())
|
||||||
|
@ -136,8 +136,8 @@ func (s *Server) handleWebSocket(c *gin.Context) {
|
|||||||
|
|
||||||
func AuthMiddleware() gin.HandlerFunc {
|
func AuthMiddleware() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
if config.GlobalConfig.Auth.Token == "" ||
|
if config.GlobalConfig.Server.Token == "" ||
|
||||||
c.Query("token") == config.GlobalConfig.Auth.Token {
|
c.Query("token") == config.GlobalConfig.Server.Token {
|
||||||
c.Next()
|
c.Next()
|
||||||
} else {
|
} else {
|
||||||
c.AbortWithStatus(http.StatusUnauthorized)
|
c.AbortWithStatus(http.StatusUnauthorized)
|
||||||
|
Loading…
Reference in New Issue
Block a user