mirror of
https://github.com/owncast/owncast.git
synced 2024-10-10 19:16:02 +00:00
Merge branch 'master' of https://github.com/gabek/owncast
This commit is contained in:
commit
d15080db11
@ -2,6 +2,6 @@ package main
|
||||
|
||||
type ChunkStorage interface {
|
||||
Setup(config Config)
|
||||
Save(filePath string) string
|
||||
Save(filePath string, retryCount int) string
|
||||
GenerateRemotePlaylist(playlist string, variant Variant) string
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
@ -24,11 +25,11 @@ type Client struct {
|
||||
func NewClient(ws *websocket.Conn, server *Server) *Client {
|
||||
|
||||
if ws == nil {
|
||||
panic("ws cannot be nil")
|
||||
log.Panicln("ws cannot be nil")
|
||||
}
|
||||
|
||||
if server == nil {
|
||||
panic("server cannot be nil")
|
||||
log.Panicln("server cannot be nil")
|
||||
}
|
||||
|
||||
ch := make(chan *ChatMessage, channelBufSize)
|
||||
|
29
config.go
29
config.go
@ -3,9 +3,6 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
@ -69,7 +66,7 @@ func getConfig() Config {
|
||||
var config Config
|
||||
err = yaml.Unmarshal(yamlFile, &config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
// fmt.Printf("%+v\n", config)
|
||||
@ -79,37 +76,37 @@ func getConfig() Config {
|
||||
|
||||
func checkConfig(config Config) {
|
||||
if config.S3.Enabled && config.IPFS.Enabled {
|
||||
panic("S3 and IPFS support cannot be enabled at the same time. Choose one.")
|
||||
log.Panicln("S3 and IPFS support cannot be enabled at the same time. Choose one.")
|
||||
}
|
||||
|
||||
if config.S3.Enabled {
|
||||
if config.S3.AccessKey == "" || config.S3.Secret == "" {
|
||||
panic("S3 support requires an access key and secret.")
|
||||
log.Panicln("S3 support requires an access key and secret.")
|
||||
}
|
||||
|
||||
if config.S3.Region == "" || config.S3.Endpoint == "" {
|
||||
panic("S3 support requires a region and endpoint.")
|
||||
log.Panicln("S3 support requires a region and endpoint.")
|
||||
}
|
||||
|
||||
if config.S3.Bucket == "" {
|
||||
panic("S3 support requires a bucket created for storing public video segments.")
|
||||
log.Panicln("S3 support requires a bucket created for storing public video segments.")
|
||||
}
|
||||
}
|
||||
|
||||
if !fileExists(config.PrivateHLSPath) {
|
||||
os.MkdirAll(path.Join(config.PrivateHLSPath, strconv.Itoa(0)), 0777)
|
||||
}
|
||||
// if !fileExists(config.PrivateHLSPath) {
|
||||
// os.MkdirAll(path.Join(config.PrivateHLSPath, strconv.Itoa(0)), 0777)
|
||||
// }
|
||||
|
||||
if !fileExists(config.PublicHLSPath) {
|
||||
os.MkdirAll(path.Join(config.PublicHLSPath, strconv.Itoa(0)), 0777)
|
||||
}
|
||||
// if !fileExists(config.PublicHLSPath) {
|
||||
// os.MkdirAll(path.Join(config.PublicHLSPath, strconv.Itoa(0)), 0777)
|
||||
// }
|
||||
|
||||
if !fileExists(config.FFMpegPath) {
|
||||
panic(fmt.Sprintf("ffmpeg does not exist at %s.", config.FFMpegPath))
|
||||
log.Panicln(fmt.Sprintf("ffmpeg does not exist at %s.", config.FFMpegPath))
|
||||
}
|
||||
|
||||
if config.VideoSettings.EncoderPreset == "" {
|
||||
panic("A video encoder preset is required to be set in the config file.")
|
||||
log.Panicln("A video encoder preset is required to be set in the config file.")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,12 +52,12 @@ func (s *IPFSStorage) Setup(config Config) {
|
||||
s.createIPFSDirectory("./hls")
|
||||
}
|
||||
|
||||
func (s *IPFSStorage) Save(filePath string) string {
|
||||
func (s *IPFSStorage) Save(filePath string, retryCount int) string {
|
||||
someFile, err := getUnixfsNode(filePath)
|
||||
defer someFile.Close()
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Could not get File: %s", err))
|
||||
log.Panicln(fmt.Errorf("Could not get File: %s", err))
|
||||
}
|
||||
|
||||
opts := []options.UnixfsAddOption{
|
||||
@ -70,7 +70,7 @@ func (s *IPFSStorage) Save(filePath string) string {
|
||||
cidFile, err := (*s.ipfs).Unixfs().Add(s.ctx, someFile, opts...)
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Could not add File: %s", err))
|
||||
log.Panicln(fmt.Errorf("Could not add File: %s", err))
|
||||
}
|
||||
|
||||
// fmt.Printf("Added file to IPFS with CID %s\n", cidFile.String())
|
||||
|
13
main.go
13
main.go
@ -37,18 +37,19 @@ func main() {
|
||||
usingExternalStorage = true
|
||||
}
|
||||
|
||||
resetDirectories(configuration)
|
||||
|
||||
if usingExternalStorage {
|
||||
storage.Setup(configuration)
|
||||
go monitorVideoContent(configuration.PrivateHLSPath, configuration, storage)
|
||||
}
|
||||
|
||||
resetDirectories(configuration)
|
||||
go startRTMPService()
|
||||
|
||||
startChatServer()
|
||||
startWebServer()
|
||||
}
|
||||
|
||||
func startChatServer() {
|
||||
func startWebServer() {
|
||||
// log.SetFlags(log.Lshortfile)
|
||||
|
||||
// websocket server
|
||||
@ -63,6 +64,7 @@ func startChatServer() {
|
||||
if path.Ext(r.URL.Path) == ".m3u8" {
|
||||
clientID := getClientIDFromRequest(r)
|
||||
stats.SetClientActive(clientID)
|
||||
disableCache(&w)
|
||||
}
|
||||
})
|
||||
|
||||
@ -77,6 +79,11 @@ func enableCors(w *http.ResponseWriter) {
|
||||
(*w).Header().Set("Access-Control-Allow-Origin", "*")
|
||||
}
|
||||
|
||||
func disableCache(w *http.ResponseWriter) {
|
||||
(*w).Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||
(*w).Header().Set("Expires", "0")
|
||||
}
|
||||
|
||||
func getStatus(w http.ResponseWriter, r *http.Request) {
|
||||
enableCors(&w)
|
||||
|
||||
|
@ -108,7 +108,7 @@ func monitorVideoContent(pathToMonitor string, configuration Config, storage Chu
|
||||
|
||||
newObjectPathChannel := make(chan string, 1)
|
||||
go func() {
|
||||
newObjectPath := storage.Save(path.Join(configuration.PrivateHLSPath, segment.RelativeUploadPath))
|
||||
newObjectPath := storage.Save(path.Join(configuration.PrivateHLSPath, segment.RelativeUploadPath), 0)
|
||||
newObjectPathChannel <- newObjectPath
|
||||
}()
|
||||
newObjectPath := <-newObjectPathChannel
|
||||
|
14
s3Storage.go
14
s3Storage.go
@ -36,14 +36,14 @@ func (s *S3Storage) Setup(configuration Config) {
|
||||
s.sess = s.connectAWS()
|
||||
}
|
||||
|
||||
func (s *S3Storage) Save(filePath string) string {
|
||||
func (s *S3Storage) Save(filePath string, retryCount int) string {
|
||||
// fmt.Println("Saving", filePath)
|
||||
|
||||
file, err := os.Open(filePath)
|
||||
defer file.Close()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Errorln(err)
|
||||
}
|
||||
|
||||
uploader := s3manager.NewUploader(s.sess)
|
||||
@ -55,7 +55,11 @@ func (s *S3Storage) Save(filePath string) string {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Errorln(err)
|
||||
if retryCount < 4 {
|
||||
log.Println("Retrying...")
|
||||
s.Save(filePath, retryCount+1)
|
||||
}
|
||||
}
|
||||
|
||||
// fmt.Println("Uploaded", filePath, "to", response.Location)
|
||||
@ -88,7 +92,7 @@ func (s S3Storage) connectAWS() *session.Session {
|
||||
creds := credentials.NewStaticCredentials(s.s3AccessKey, s.s3Secret, "")
|
||||
_, err := creds.Get()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
sess, err := session.NewSession(
|
||||
@ -101,7 +105,7 @@ func (s S3Storage) connectAWS() *session.Session {
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Panicln(err)
|
||||
}
|
||||
return sess
|
||||
}
|
||||
|
@ -9,6 +9,11 @@ ARCH=(amd64 amd64)
|
||||
|
||||
# Version
|
||||
VERSION=$1
|
||||
|
||||
if [[ -z "${VERSION}" ]]; then
|
||||
echo "Version must be specified when running build"
|
||||
fi
|
||||
|
||||
[[ -z "${VERSION}" ]] && VERSION='unknownver' || VERSION="${VERSION}"
|
||||
GIT_COMMIT=$(git rev-list -1 HEAD)
|
||||
|
||||
@ -33,7 +38,10 @@ build() {
|
||||
|
||||
mkdir -p dist/${NAME}/config
|
||||
|
||||
# Default files
|
||||
cp config/config-example.yaml dist/${NAME}/config/config.yaml
|
||||
cp webroot/static/content-example.md dist/${NAME}/webroot/static/content.md
|
||||
|
||||
cp -R webroot/ dist/${NAME}/webroot/
|
||||
cp -R doc/ dist/${NAME}/doc/
|
||||
cp README.md dist/${NAME}
|
||||
|
2
stats.go
2
stats.go
@ -145,7 +145,7 @@ func getSavedStats() *Stats {
|
||||
var stats Stats
|
||||
err = json.Unmarshal(jsonFile, &stats)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
return &stats
|
||||
|
@ -8,9 +8,9 @@
|
||||
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
|
||||
|
||||
<link href="https://vjs.zencdn.net/7.8.2/video-js.css" rel="stylesheet">
|
||||
<link href="//unpkg.com/video.js@7.8.3/dist/video-js.css" rel="stylesheet">
|
||||
<link href="https://unpkg.com/@videojs/themes@1/dist/fantasy/index.css" rel="stylesheet" />
|
||||
<script src="//vjs.zencdn.net/7.8.2/video.js"></script>
|
||||
<script src="//unpkg.com/video.js@7.8.3/dist/video.js"></script>
|
||||
<script src="//unpkg.com/showdown/dist/showdown.min.js"></script>
|
||||
<script src="vendor/autolink.js"></script>
|
||||
<link href="./styles/layout.css" rel="stylesheet" />
|
||||
|
@ -47,13 +47,10 @@ async function setupApp() {
|
||||
const response = await fetch(pageContentFile);
|
||||
const descriptionMarkdown = await response.text()
|
||||
const descriptionHTML = new showdown.Converter().makeHtml(descriptionMarkdown);
|
||||
console.log(descriptionHTML)
|
||||
app.description = descriptionHTML;
|
||||
// Object.assign(this, configData);
|
||||
return this;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// No config file present. That's ok. It's not required.
|
||||
}
|
||||
}
|
||||
|
||||
|
4
webroot/static/content-example.md
Normal file
4
webroot/static/content-example.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Stream description and content can go here.
|
||||
|
||||
1. Edit `content.md` in markdown.
|
||||
1. And it'll go here.
|
Loading…
x
Reference in New Issue
Block a user