This commit is contained in:
Ginger Wong 2020-06-18 00:12:39 -07:00
commit d15080db11
12 changed files with 55 additions and 37 deletions

View File

@ -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
}

View File

@ -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)

View File

@ -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.")
}
}

View 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
View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -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}

View File

@ -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

View File

@ -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" />

View File

@ -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.
}
}

View File

@ -0,0 +1,4 @@
# Stream description and content can go here.
1. Edit `content.md` in markdown.
1. And it'll go here.