mirror of
https://github.com/owncast/owncast.git
synced 2024-11-22 04:40:37 +03:00
Fix godoc style comments (#356)
This commit is contained in:
parent
8f921fbfde
commit
2e1f8d29b5
59 changed files with 147 additions and 147 deletions
|
@ -11,7 +11,7 @@ import (
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Config contains a reference to the configuration
|
// Config contains a reference to the configuration.
|
||||||
var Config *config
|
var Config *config
|
||||||
var _default config
|
var _default config
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ type files struct {
|
||||||
MaxNumberInPlaylist int `yaml:"maxNumberInPlaylist"`
|
MaxNumberInPlaylist int `yaml:"maxNumberInPlaylist"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//S3 is for configuring the S3 integration
|
// S3 is for configuring the S3 integration.
|
||||||
type S3 struct {
|
type S3 struct {
|
||||||
Enabled bool `yaml:"enabled" json:"enabled"`
|
Enabled bool `yaml:"enabled" json:"enabled"`
|
||||||
Endpoint string `yaml:"endpoint" json:"endpoint,omitempty"`
|
Endpoint string `yaml:"endpoint" json:"endpoint,omitempty"`
|
||||||
|
@ -229,7 +229,7 @@ func (c *config) GetVideoStreamQualities() []StreamQuality {
|
||||||
return _default.VideoSettings.StreamQualities
|
return _default.VideoSettings.StreamQualities
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFramerate returns the framerate or default
|
// GetFramerate returns the framerate or default.
|
||||||
func (q *StreamQuality) GetFramerate() int {
|
func (q *StreamQuality) GetFramerate() int {
|
||||||
if q.Framerate > 0 {
|
if q.Framerate > 0 {
|
||||||
return q.Framerate
|
return q.Framerate
|
||||||
|
@ -238,7 +238,7 @@ func (q *StreamQuality) GetFramerate() int {
|
||||||
return _default.VideoSettings.StreamQualities[0].Framerate
|
return _default.VideoSettings.StreamQualities[0].Framerate
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEncoderPreset returns the preset or default
|
// GetEncoderPreset returns the preset or default.
|
||||||
func (q *StreamQuality) GetEncoderPreset() string {
|
func (q *StreamQuality) GetEncoderPreset() string {
|
||||||
if q.EncoderPreset != "" {
|
if q.EncoderPreset != "" {
|
||||||
return q.EncoderPreset
|
return q.EncoderPreset
|
||||||
|
@ -247,7 +247,7 @@ func (q *StreamQuality) GetEncoderPreset() string {
|
||||||
return _default.VideoSettings.StreamQualities[0].EncoderPreset
|
return _default.VideoSettings.StreamQualities[0].EncoderPreset
|
||||||
}
|
}
|
||||||
|
|
||||||
//Load tries to load the configuration file
|
// Load tries to load the configuration file.
|
||||||
func Load(filePath string, versionInfo string, versionNumber string) error {
|
func Load(filePath string, versionInfo string, versionNumber string) error {
|
||||||
Config = new(config)
|
Config = new(config)
|
||||||
_default = getDefaults()
|
_default = getDefaults()
|
||||||
|
|
|
@ -36,7 +36,7 @@ func findHighestQuality(qualities []StreamQuality) int {
|
||||||
return indexedQualities[0].index
|
return indexedQualities[0].index
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON is a custom JSON marshal function for video stream qualities
|
// MarshalJSON is a custom JSON marshal function for video stream qualities.
|
||||||
func (q *StreamQuality) MarshalJSON() ([]byte, error) {
|
func (q *StreamQuality) MarshalJSON() ([]byte, error) {
|
||||||
type Alias StreamQuality
|
type Alias StreamQuality
|
||||||
return json.Marshal(&struct {
|
return json.Marshal(&struct {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
//verifyFFMpegPath verifies that the path exists, is a file, and is executable
|
// verifyFFMpegPath verifies that the path exists, is a file, and is executable.
|
||||||
func verifyFFMpegPath(path string) error {
|
func verifyFFMpegPath(path string) error {
|
||||||
stat, err := os.Stat(path)
|
stat, err := os.Stat(path)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/owncast/owncast/core/rtmp"
|
"github.com/owncast/owncast/core/rtmp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DisconnectInboundConnection will force-disconnect an inbound stream
|
// DisconnectInboundConnection will force-disconnect an inbound stream.
|
||||||
func DisconnectInboundConnection(w http.ResponseWriter, r *http.Request) {
|
func DisconnectInboundConnection(w http.ResponseWriter, r *http.Request) {
|
||||||
rtmp.Disconnect()
|
rtmp.Disconnect()
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChangeExtraPageContent will change the optional page content
|
// ChangeExtraPageContent will change the optional page content.
|
||||||
func ChangeExtraPageContent(w http.ResponseWriter, r *http.Request) {
|
func ChangeExtraPageContent(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "POST" {
|
if r.Method != "POST" {
|
||||||
controllers.WriteSimpleResponse(w, false, r.Method+" not supported")
|
controllers.WriteSimpleResponse(w, false, r.Method+" not supported")
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChangeStreamKey will change the stream key (in memory)
|
// ChangeStreamKey will change the stream key (in memory).
|
||||||
func ChangeStreamKey(w http.ResponseWriter, r *http.Request) {
|
func ChangeStreamKey(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != "POST" {
|
if r.Method != "POST" {
|
||||||
controllers.WriteSimpleResponse(w, false, r.Method+" not supported")
|
controllers.WriteSimpleResponse(w, false, r.Method+" not supported")
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/owncast/owncast/core/rtmp"
|
"github.com/owncast/owncast/core/rtmp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DisconnectInboundConnection will force-disconnect an inbound stream
|
// DisconnectInboundConnection will force-disconnect an inbound stream.
|
||||||
func DisconnectInboundConnection(w http.ResponseWriter, r *http.Request) {
|
func DisconnectInboundConnection(w http.ResponseWriter, r *http.Request) {
|
||||||
if !core.GetStatus().Online {
|
if !core.GetStatus().Online {
|
||||||
controllers.WriteSimpleResponse(w, false, "no inbound stream connected")
|
controllers.WriteSimpleResponse(w, false, "no inbound stream connected")
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/owncast/owncast/metrics"
|
"github.com/owncast/owncast/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetHardwareStats will return hardware utilization over time
|
// GetHardwareStats will return hardware utilization over time.
|
||||||
func GetHardwareStats(w http.ResponseWriter, r *http.Request) {
|
func GetHardwareStats(w http.ResponseWriter, r *http.Request) {
|
||||||
m := metrics.Metrics
|
m := metrics.Metrics
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ServeAdmin will return admin web assets
|
// ServeAdmin will return admin web assets.
|
||||||
func ServeAdmin(w http.ResponseWriter, r *http.Request) {
|
func ServeAdmin(w http.ResponseWriter, r *http.Request) {
|
||||||
// Set a cache control max-age header
|
// Set a cache control max-age header
|
||||||
middleware.SetCachingHeaders(w, r)
|
middleware.SetCachingHeaders(w, r)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetLogs will return all logs
|
// GetLogs will return all logs.
|
||||||
func GetLogs(w http.ResponseWriter, r *http.Request) {
|
func GetLogs(w http.ResponseWriter, r *http.Request) {
|
||||||
logs := logging.Logger.AllEntries()
|
logs := logging.Logger.AllEntries()
|
||||||
response := make([]logsResponse, 0)
|
response := make([]logsResponse, 0)
|
||||||
|
@ -22,7 +22,7 @@ func GetLogs(w http.ResponseWriter, r *http.Request) {
|
||||||
json.NewEncoder(w).Encode(response)
|
json.NewEncoder(w).Encode(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWarnings will return only warning and error logs
|
// GetWarnings will return only warning and error logs.
|
||||||
func GetWarnings(w http.ResponseWriter, r *http.Request) {
|
func GetWarnings(w http.ResponseWriter, r *http.Request) {
|
||||||
logs := logging.Logger.WarningEntries()
|
logs := logging.Logger.WarningEntries()
|
||||||
response := make([]logsResponse, 0)
|
response := make([]logsResponse, 0)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/owncast/owncast/config"
|
"github.com/owncast/owncast/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetServerConfig gets the config details of the server
|
// GetServerConfig gets the config details of the server.
|
||||||
func GetServerConfig(w http.ResponseWriter, r *http.Request) {
|
func GetServerConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
var videoQualityVariants = make([]config.StreamQuality, 0)
|
var videoQualityVariants = make([]config.StreamQuality, 0)
|
||||||
for _, variant := range config.Config.GetVideoStreamQualities() {
|
for _, variant := range config.Config.GetVideoStreamQualities() {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/owncast/owncast/models"
|
"github.com/owncast/owncast/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Status gets the details of the inbound broadcaster
|
// Status gets the details of the inbound broadcaster.
|
||||||
func Status(w http.ResponseWriter, r *http.Request) {
|
func Status(w http.ResponseWriter, r *http.Request) {
|
||||||
broadcaster := core.GetBroadcaster()
|
broadcaster := core.GetBroadcaster()
|
||||||
status := core.GetStatus()
|
status := core.GetStatus()
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/owncast/owncast/metrics"
|
"github.com/owncast/owncast/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetViewersOverTime will return the number of viewers at points in time
|
// GetViewersOverTime will return the number of viewers at points in time.
|
||||||
func GetViewersOverTime(w http.ResponseWriter, r *http.Request) {
|
func GetViewersOverTime(w http.ResponseWriter, r *http.Request) {
|
||||||
viewersOverTime := metrics.Metrics.Viewers
|
viewersOverTime := metrics.Metrics.Viewers
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/owncast/owncast/router/middleware"
|
"github.com/owncast/owncast/router/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
//GetChatMessages gets all of the chat messages
|
// GetChatMessages gets all of the chat messages.
|
||||||
func GetChatMessages(w http.ResponseWriter, r *http.Request) {
|
func GetChatMessages(w http.ResponseWriter, r *http.Request) {
|
||||||
middleware.EnableCors(&w)
|
middleware.EnableCors(&w)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/owncast/owncast/router/middleware"
|
"github.com/owncast/owncast/router/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
//GetWebConfig gets the status of the server
|
// GetWebConfig gets the status of the server.
|
||||||
func GetWebConfig(w http.ResponseWriter, r *http.Request) {
|
func GetWebConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
middleware.EnableCors(&w)
|
middleware.EnableCors(&w)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/owncast/owncast/core"
|
"github.com/owncast/owncast/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetConnectedClients returns currently connected clients
|
// GetConnectedClients returns currently connected clients.
|
||||||
func GetConnectedClients(w http.ResponseWriter, r *http.Request) {
|
func GetConnectedClients(w http.ResponseWriter, r *http.Request) {
|
||||||
clients := core.GetClients()
|
clients := core.GetClients()
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
|
@ -4,12 +4,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
//GetChatEmbed gets the embed for chat
|
// GetChatEmbed gets the embed for chat.
|
||||||
func GetChatEmbed(w http.ResponseWriter, r *http.Request) {
|
func GetChatEmbed(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, "/index-standalone-chat.html", http.StatusMovedPermanently)
|
http.Redirect(w, r, "/index-standalone-chat.html", http.StatusMovedPermanently)
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetVideoEmbed gets the embed for video
|
// GetVideoEmbed gets the embed for video.
|
||||||
func GetVideoEmbed(w http.ResponseWriter, r *http.Request) {
|
func GetVideoEmbed(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, "/index-video-only.html", http.StatusMovedPermanently)
|
http.Redirect(w, r, "/index-video-only.html", http.StatusMovedPermanently)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import (
|
||||||
// to need it to be. The config is getting a bit bloated.
|
// to need it to be. The config is getting a bit bloated.
|
||||||
const emojiDir = "/img/emoji" // Relative to webroot
|
const emojiDir = "/img/emoji" // Relative to webroot
|
||||||
|
|
||||||
//GetCustomEmoji returns a list of custom emoji via the API
|
// GetCustomEmoji returns a list of custom emoji via the API.
|
||||||
func GetCustomEmoji(w http.ResponseWriter, r *http.Request) {
|
func GetCustomEmoji(w http.ResponseWriter, r *http.Request) {
|
||||||
emojiList := make([]models.CustomEmoji, 0)
|
emojiList := make([]models.CustomEmoji, 0)
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ type MetadataPage struct {
|
||||||
TagsString string
|
TagsString string
|
||||||
}
|
}
|
||||||
|
|
||||||
//IndexHandler handles the default index route
|
// IndexHandler handles the default index route.
|
||||||
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
func IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
middleware.EnableCors(&w)
|
middleware.EnableCors(&w)
|
||||||
isIndexRequest := r.URL.Path == "/" || filepath.Base(r.URL.Path) == "index.html" || filepath.Base(r.URL.Path) == ""
|
isIndexRequest := r.URL.Path == "/" || filepath.Base(r.URL.Path) == "index.html" || filepath.Base(r.URL.Path) == ""
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/owncast/owncast/router/middleware"
|
"github.com/owncast/owncast/router/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
//GetStatus gets the status of the server
|
// GetStatus gets the status of the server.
|
||||||
func GetStatus(w http.ResponseWriter, r *http.Request) {
|
func GetStatus(w http.ResponseWriter, r *http.Request) {
|
||||||
middleware.EnableCors(&w)
|
middleware.EnableCors(&w)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/owncast/owncast/models"
|
"github.com/owncast/owncast/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Setup sets up the chat server
|
// Setup sets up the chat server.
|
||||||
func Setup(listener models.ChatListener) {
|
func Setup(listener models.ChatListener) {
|
||||||
setupPersistence()
|
setupPersistence()
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ func Setup(listener models.ChatListener) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Start starts the chat server
|
// Start starts the chat server.
|
||||||
func Start() error {
|
func Start() error {
|
||||||
if _server == nil {
|
if _server == nil {
|
||||||
return errors.New("chat server is nil")
|
return errors.New("chat server is nil")
|
||||||
|
@ -53,7 +53,7 @@ func Start() error {
|
||||||
return errors.New("chat server failed to start")
|
return errors.New("chat server failed to start")
|
||||||
}
|
}
|
||||||
|
|
||||||
//SendMessage sends a message to all
|
// SendMessage sends a message to all.
|
||||||
func SendMessage(message models.ChatMessage) {
|
func SendMessage(message models.ChatMessage) {
|
||||||
if _server == nil {
|
if _server == nil {
|
||||||
return
|
return
|
||||||
|
@ -62,7 +62,7 @@ func SendMessage(message models.ChatMessage) {
|
||||||
_server.SendToAll(message)
|
_server.SendToAll(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetMessages gets all of the messages
|
// GetMessages gets all of the messages.
|
||||||
func GetMessages() []models.ChatMessage {
|
func GetMessages() []models.ChatMessage {
|
||||||
if _server == nil {
|
if _server == nil {
|
||||||
return []models.ChatMessage{}
|
return []models.ChatMessage{}
|
||||||
|
|
|
@ -44,7 +44,7 @@ const (
|
||||||
PONG = "PONG"
|
PONG = "PONG"
|
||||||
)
|
)
|
||||||
|
|
||||||
//NewClient creates a new chat client
|
// NewClient creates a new chat client.
|
||||||
func NewClient(ws *websocket.Conn) *Client {
|
func NewClient(ws *websocket.Conn) *Client {
|
||||||
if ws == nil {
|
if ws == nil {
|
||||||
log.Panicln("ws cannot be nil")
|
log.Panicln("ws cannot be nil")
|
||||||
|
@ -63,7 +63,7 @@ func NewClient(ws *websocket.Conn) *Client {
|
||||||
return &Client{time.Now(), 0, userAgent, ipAddress, nil, clientID, nil, socketID, ws, ch, pingch, usernameChangeChannel, doneCh}
|
return &Client{time.Now(), 0, userAgent, ipAddress, nil, clientID, nil, socketID, ws, ch, pingch, usernameChangeChannel, doneCh}
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetConnection gets the connection for the client
|
// GetConnection gets the connection for the client.
|
||||||
func (c *Client) GetConnection() *websocket.Conn {
|
func (c *Client) GetConnection() *websocket.Conn {
|
||||||
return c.ws
|
return c.ws
|
||||||
}
|
}
|
||||||
|
@ -77,18 +77,18 @@ func (c *Client) Write(msg models.ChatMessage) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Done marks the client as done
|
// Done marks the client as done.
|
||||||
func (c *Client) Done() {
|
func (c *Client) Done() {
|
||||||
c.doneCh <- true
|
c.doneCh <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen Write and Read request via chanel
|
// Listen Write and Read request via channel.
|
||||||
func (c *Client) Listen() {
|
func (c *Client) Listen() {
|
||||||
go c.listenWrite()
|
go c.listenWrite()
|
||||||
c.listenRead()
|
c.listenRead()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen write request via chanel
|
// Listen write request via channel.
|
||||||
func (c *Client) listenWrite() {
|
func (c *Client) listenWrite() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -110,7 +110,7 @@ func (c *Client) listenWrite() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen read request via chanel
|
// Listen read request via channel.
|
||||||
func (c *Client) listenRead() {
|
func (c *Client) listenRead() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|
|
@ -16,7 +16,7 @@ var (
|
||||||
_server *server
|
_server *server
|
||||||
)
|
)
|
||||||
|
|
||||||
//Server represents the server which handles the chat
|
// Server represents the server which handles the chat.
|
||||||
type server struct {
|
type server struct {
|
||||||
Clients map[string]*Client
|
Clients map[string]*Client
|
||||||
|
|
||||||
|
@ -31,27 +31,27 @@ type server struct {
|
||||||
errCh chan error
|
errCh chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add adds a client to the server
|
// Add adds a client to the server.
|
||||||
func (s *server) add(c *Client) {
|
func (s *server) add(c *Client) {
|
||||||
s.addCh <- c
|
s.addCh <- c
|
||||||
}
|
}
|
||||||
|
|
||||||
//Remove removes a client from the server
|
// Remove removes a client from the server.
|
||||||
func (s *server) remove(c *Client) {
|
func (s *server) remove(c *Client) {
|
||||||
s.delCh <- c
|
s.delCh <- c
|
||||||
}
|
}
|
||||||
|
|
||||||
//SendToAll sends a message to all of the connected clients
|
// SendToAll sends a message to all of the connected clients.
|
||||||
func (s *server) SendToAll(msg models.ChatMessage) {
|
func (s *server) SendToAll(msg models.ChatMessage) {
|
||||||
s.sendAllCh <- msg
|
s.sendAllCh <- msg
|
||||||
}
|
}
|
||||||
|
|
||||||
//Done marks the server as done
|
// Done marks the server as done.
|
||||||
func (s *server) done() {
|
func (s *server) done() {
|
||||||
s.doneCh <- true
|
s.doneCh <- true
|
||||||
}
|
}
|
||||||
|
|
||||||
//Err handles an error
|
// Err handles an error.
|
||||||
func (s *server) err(err error) {
|
func (s *server) err(err error) {
|
||||||
s.errCh <- err
|
s.errCh <- err
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,24 @@ import (
|
||||||
"github.com/owncast/owncast/models"
|
"github.com/owncast/owncast/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
//ChatListenerImpl the implementation of the chat client
|
// ChatListenerImpl the implementation of the chat client.
|
||||||
type ChatListenerImpl struct{}
|
type ChatListenerImpl struct{}
|
||||||
|
|
||||||
//ClientAdded is for when a client is added the system
|
// ClientAdded is for when a client is added the system.
|
||||||
func (cl ChatListenerImpl) ClientAdded(client models.Client) {
|
func (cl ChatListenerImpl) ClientAdded(client models.Client) {
|
||||||
SetClientActive(client)
|
SetClientActive(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
//ClientRemoved is for when a client disconnects/is removed
|
// ClientRemoved is for when a client disconnects/is removed.
|
||||||
func (cl ChatListenerImpl) ClientRemoved(clientID string) {
|
func (cl ChatListenerImpl) ClientRemoved(clientID string) {
|
||||||
RemoveClient(clientID)
|
RemoveClient(clientID)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MessageSent is for when a message is sent
|
// MessageSent is for when a message is sent.
|
||||||
func (cl ChatListenerImpl) MessageSent(message models.ChatMessage) {
|
func (cl ChatListenerImpl) MessageSent(message models.ChatMessage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//SendMessageToChat sends a message to the chat server
|
// SendMessageToChat sends a message to the chat server.
|
||||||
func SendMessageToChat(message models.ChatMessage) error {
|
func SendMessageToChat(message models.ChatMessage) error {
|
||||||
if !message.Valid() {
|
if !message.Valid() {
|
||||||
return errors.New("invalid chat message; id, author, and body are required")
|
return errors.New("invalid chat message; id, author, and body are required")
|
||||||
|
@ -35,7 +35,7 @@ func SendMessageToChat(message models.ChatMessage) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetAllChatMessages gets all of the chat messages
|
// GetAllChatMessages gets all of the chat messages.
|
||||||
func GetAllChatMessages() []models.ChatMessage {
|
func GetAllChatMessages() []models.ChatMessage {
|
||||||
return chat.GetMessages()
|
return chat.GetMessages()
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ var (
|
||||||
var handler ffmpeg.HLSHandler
|
var handler ffmpeg.HLSHandler
|
||||||
var fileWriter = ffmpeg.FileWriterReceiverService{}
|
var fileWriter = ffmpeg.FileWriterReceiverService{}
|
||||||
|
|
||||||
//Start starts up the core processing
|
// Start starts up the core processing.
|
||||||
func Start() error {
|
func Start() error {
|
||||||
resetDirectories()
|
resetDirectories()
|
||||||
|
|
||||||
|
|
|
@ -15,19 +15,19 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// FileWriterReceiverServiceCallback are to be fired when transcoder responses are written to disk
|
// FileWriterReceiverServiceCallback are to be fired when transcoder responses are written to disk.
|
||||||
type FileWriterReceiverServiceCallback interface {
|
type FileWriterReceiverServiceCallback interface {
|
||||||
SegmentWritten(localFilePath string)
|
SegmentWritten(localFilePath string)
|
||||||
VariantPlaylistWritten(localFilePath string)
|
VariantPlaylistWritten(localFilePath string)
|
||||||
MasterPlaylistWritten(localFilePath string)
|
MasterPlaylistWritten(localFilePath string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileWriterReceiverService accepts transcoder responses via HTTP and fires the callbacks
|
// FileWriterReceiverService accepts transcoder responses via HTTP and fires the callbacks.
|
||||||
type FileWriterReceiverService struct {
|
type FileWriterReceiverService struct {
|
||||||
callbacks FileWriterReceiverServiceCallback
|
callbacks FileWriterReceiverServiceCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupFileWriterReceiverService will start listening for transcoder responses
|
// SetupFileWriterReceiverService will start listening for transcoder responses.
|
||||||
func (s *FileWriterReceiverService) SetupFileWriterReceiverService(callbacks FileWriterReceiverServiceCallback) {
|
func (s *FileWriterReceiverService) SetupFileWriterReceiverService(callbacks FileWriterReceiverServiceCallback) {
|
||||||
s.callbacks = callbacks
|
s.callbacks = callbacks
|
||||||
|
|
||||||
|
|
|
@ -4,22 +4,22 @@ import (
|
||||||
"github.com/owncast/owncast/models"
|
"github.com/owncast/owncast/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HLSHandler gets told about available HLS playlists and segments
|
// HLSHandler gets told about available HLS playlists and segments.
|
||||||
type HLSHandler struct {
|
type HLSHandler struct {
|
||||||
Storage models.StorageProvider
|
Storage models.StorageProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
// SegmentWritten is fired when a HLS segment is written to disk
|
// SegmentWritten is fired when a HLS segment is written to disk.
|
||||||
func (h *HLSHandler) SegmentWritten(localFilePath string) {
|
func (h *HLSHandler) SegmentWritten(localFilePath string) {
|
||||||
h.Storage.SegmentWritten(localFilePath)
|
h.Storage.SegmentWritten(localFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VariantPlaylistWritten is fired when a HLS variant playlist is written to disk
|
// VariantPlaylistWritten is fired when a HLS variant playlist is written to disk.
|
||||||
func (h *HLSHandler) VariantPlaylistWritten(localFilePath string) {
|
func (h *HLSHandler) VariantPlaylistWritten(localFilePath string) {
|
||||||
h.Storage.VariantPlaylistWritten(localFilePath)
|
h.Storage.VariantPlaylistWritten(localFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MasterPlaylistWritten is fired when a HLS master playlist is written to disk
|
// MasterPlaylistWritten is fired when a HLS master playlist is written to disk.
|
||||||
func (h *HLSHandler) MasterPlaylistWritten(localFilePath string) {
|
func (h *HLSHandler) MasterPlaylistWritten(localFilePath string) {
|
||||||
h.Storage.MasterPlaylistWritten(localFilePath)
|
h.Storage.MasterPlaylistWritten(localFilePath)
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ func StopThumbnailGenerator() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//StartThumbnailGenerator starts generating thumbnails
|
// StartThumbnailGenerator starts generating thumbnails.
|
||||||
func StartThumbnailGenerator(chunkPath string, variantIndex int) {
|
func StartThumbnailGenerator(chunkPath string, variantIndex int) {
|
||||||
// Every 20 seconds create a thumbnail from the most
|
// Every 20 seconds create a thumbnail from the most
|
||||||
// recent video segment.
|
// recent video segment.
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
|
|
||||||
var _commandExec *exec.Cmd
|
var _commandExec *exec.Cmd
|
||||||
|
|
||||||
// Transcoder is a single instance of a video transcoder
|
// Transcoder is a single instance of a video transcoder.
|
||||||
type Transcoder struct {
|
type Transcoder struct {
|
||||||
input string
|
input string
|
||||||
segmentOutputPath string
|
segmentOutputPath string
|
||||||
|
@ -30,7 +30,7 @@ type Transcoder struct {
|
||||||
TranscoderCompleted func(error)
|
TranscoderCompleted func(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HLSVariant is a combination of settings that results in a single HLS stream
|
// HLSVariant is a combination of settings that results in a single HLS stream.
|
||||||
type HLSVariant struct {
|
type HLSVariant struct {
|
||||||
index int
|
index int
|
||||||
|
|
||||||
|
@ -45,13 +45,13 @@ type HLSVariant struct {
|
||||||
encoderPreset string // A collection of automatic settings for the encoder. https://trac.ffmpeg.org/wiki/Encode/H.264#crf
|
encoderPreset string // A collection of automatic settings for the encoder. https://trac.ffmpeg.org/wiki/Encode/H.264#crf
|
||||||
}
|
}
|
||||||
|
|
||||||
// VideoSize is the scaled size of the video output
|
// VideoSize is the scaled size of the video output.
|
||||||
type VideoSize struct {
|
type VideoSize struct {
|
||||||
Width int
|
Width int
|
||||||
Height int
|
Height int
|
||||||
}
|
}
|
||||||
|
|
||||||
// getString returns a WxH formatted getString for scaling video output
|
// getString returns a WxH formatted getString for scaling video output.
|
||||||
func (v *VideoSize) getString() string {
|
func (v *VideoSize) getString() string {
|
||||||
widthString := strconv.Itoa(v.Width)
|
widthString := strconv.Itoa(v.Width)
|
||||||
heightString := strconv.Itoa(v.Height)
|
heightString := strconv.Itoa(v.Height)
|
||||||
|
@ -197,7 +197,7 @@ func getVariantFromConfigQuality(quality config.StreamQuality, index int) HLSVar
|
||||||
return variant
|
return variant
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTranscoder will return a new Transcoder, populated by the config
|
// NewTranscoder will return a new Transcoder, populated by the config.
|
||||||
func NewTranscoder() *Transcoder {
|
func NewTranscoder() *Transcoder {
|
||||||
transcoder := new(Transcoder)
|
transcoder := new(Transcoder)
|
||||||
transcoder.ffmpegPath = config.Config.GetFFMpegPath()
|
transcoder.ffmpegPath = config.Config.GetFFMpegPath()
|
||||||
|
@ -248,7 +248,7 @@ func (v *HLSVariant) getVariantString(t *Transcoder) string {
|
||||||
return strings.Join(variantEncoderCommands, " ")
|
return strings.Join(variantEncoderCommands, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the command flags for the variants
|
// Get the command flags for the variants.
|
||||||
func (t *Transcoder) getVariantsString() string {
|
func (t *Transcoder) getVariantsString() string {
|
||||||
var variantsCommandFlags = ""
|
var variantsCommandFlags = ""
|
||||||
var variantsStreamMaps = " -var_stream_map \""
|
var variantsStreamMaps = " -var_stream_map \""
|
||||||
|
@ -267,12 +267,12 @@ func (t *Transcoder) getVariantsString() string {
|
||||||
// If we'd like to keep the aspect ratio, we need to specify only one component, either width or height.
|
// If we'd like to keep the aspect ratio, we need to specify only one component, either width or height.
|
||||||
// Some codecs require the size of width and height to be a multiple of n. You can achieve this by setting the width or height to -n.
|
// Some codecs require the size of width and height to be a multiple of n. You can achieve this by setting the width or height to -n.
|
||||||
|
|
||||||
// SetVideoScalingWidth will set the scaled video width of this variant
|
// SetVideoScalingWidth will set the scaled video width of this variant.
|
||||||
func (v *HLSVariant) SetVideoScalingWidth(width int) {
|
func (v *HLSVariant) SetVideoScalingWidth(width int) {
|
||||||
v.videoSize.Width = width
|
v.videoSize.Width = width
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVideoScalingHeight will set the scaled video height of this variant
|
// SetVideoScalingHeight will set the scaled video height of this variant.
|
||||||
func (v *HLSVariant) SetVideoScalingHeight(height int) {
|
func (v *HLSVariant) SetVideoScalingHeight(height int) {
|
||||||
v.videoSize.Height = height
|
v.videoSize.Height = height
|
||||||
}
|
}
|
||||||
|
@ -284,7 +284,7 @@ func (v *HLSVariant) getScalingString() string {
|
||||||
|
|
||||||
// Video Quality
|
// Video Quality
|
||||||
|
|
||||||
// SetVideoBitrate will set the output bitrate of this variant's video
|
// SetVideoBitrate will set the output bitrate of this variant's video.
|
||||||
func (v *HLSVariant) SetVideoBitrate(bitrate int) {
|
func (v *HLSVariant) SetVideoBitrate(bitrate int) {
|
||||||
v.videoBitrate = bitrate
|
v.videoBitrate = bitrate
|
||||||
}
|
}
|
||||||
|
@ -321,19 +321,19 @@ func (v *HLSVariant) getVideoQualityString(t *Transcoder) string {
|
||||||
return strings.Join(cmd, " ")
|
return strings.Join(cmd, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetVideoFramerate will set the output framerate of this variant's video
|
// SetVideoFramerate will set the output framerate of this variant's video.
|
||||||
func (v *HLSVariant) SetVideoFramerate(framerate int) {
|
func (v *HLSVariant) SetVideoFramerate(framerate int) {
|
||||||
v.framerate = framerate
|
v.framerate = framerate
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetEncoderPreset will set the video encoder preset of this variant
|
// SetEncoderPreset will set the video encoder preset of this variant.
|
||||||
func (v *HLSVariant) SetEncoderPreset(preset string) {
|
func (v *HLSVariant) SetEncoderPreset(preset string) {
|
||||||
v.encoderPreset = preset
|
v.encoderPreset = preset
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audio Quality
|
// Audio Quality
|
||||||
|
|
||||||
// SetAudioBitrate will set the output framerate of this variant's audio
|
// SetAudioBitrate will set the output framerate of this variant's audio.
|
||||||
func (v *HLSVariant) SetAudioBitrate(bitrate string) {
|
func (v *HLSVariant) SetAudioBitrate(bitrate string) {
|
||||||
v.audioBitrate = bitrate
|
v.audioBitrate = bitrate
|
||||||
}
|
}
|
||||||
|
@ -348,38 +348,38 @@ func (v *HLSVariant) getAudioQualityString() string {
|
||||||
return fmt.Sprintf("-map a:0 -c:a:%d %s -b:a:%d %s", v.index, encoderCodec, v.index, v.audioBitrate)
|
return fmt.Sprintf("-map a:0 -c:a:%d %s -b:a:%d %s", v.index, encoderCodec, v.index, v.audioBitrate)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddVariant adds a new HLS variant to include in the output
|
// AddVariant adds a new HLS variant to include in the output.
|
||||||
func (t *Transcoder) AddVariant(variant HLSVariant) {
|
func (t *Transcoder) AddVariant(variant HLSVariant) {
|
||||||
variant.index = len(t.variants)
|
variant.index = len(t.variants)
|
||||||
t.variants = append(t.variants, variant)
|
t.variants = append(t.variants, variant)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetInput sets the input stream on the filesystem
|
// SetInput sets the input stream on the filesystem.
|
||||||
func (t *Transcoder) SetInput(input string) {
|
func (t *Transcoder) SetInput(input string) {
|
||||||
t.input = input
|
t.input = input
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetOutputPath sets the root directory that should include playlists and video segments
|
// SetOutputPath sets the root directory that should include playlists and video segments.
|
||||||
func (t *Transcoder) SetOutputPath(output string) {
|
func (t *Transcoder) SetOutputPath(output string) {
|
||||||
t.segmentOutputPath = output
|
t.segmentOutputPath = output
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHLSPlaylistLength will set the max number of items in a HLS variant's playlist
|
// SetHLSPlaylistLength will set the max number of items in a HLS variant's playlist.
|
||||||
func (t *Transcoder) SetHLSPlaylistLength(length int) {
|
func (t *Transcoder) SetHLSPlaylistLength(length int) {
|
||||||
t.hlsPlaylistLength = length
|
t.hlsPlaylistLength = length
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSegmentLength Specifies the number of seconds each segment should be
|
// SetSegmentLength Specifies the number of seconds each segment should be.
|
||||||
func (t *Transcoder) SetSegmentLength(seconds int) {
|
func (t *Transcoder) SetSegmentLength(seconds int) {
|
||||||
t.segmentLengthSeconds = seconds
|
t.segmentLengthSeconds = seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAppendToStream enables appending to the HLS stream instead of overwriting
|
// SetAppendToStream enables appending to the HLS stream instead of overwriting.
|
||||||
func (t *Transcoder) SetAppendToStream(append bool) {
|
func (t *Transcoder) SetAppendToStream(append bool) {
|
||||||
t.appendToStream = append
|
t.appendToStream = append
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetIdentifer enables appending a unique identifier to segment file name
|
// SetIdentifer enables appending a unique identifier to segment file name.
|
||||||
func (t *Transcoder) SetIdentifier(output string) {
|
func (t *Transcoder) SetIdentifier(output string) {
|
||||||
t.segmentIdentifier = output
|
t.segmentIdentifier = output
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package playlist
|
||||||
|
|
||||||
import "os"
|
import "os"
|
||||||
|
|
||||||
//WritePlaylist writes the playlist to disk
|
// WritePlaylist writes the playlist to disk.
|
||||||
func WritePlaylist(data string, filePath string) error {
|
func WritePlaylist(data string, filePath string) error {
|
||||||
f, err := os.Create(filePath)
|
f, err := os.Create(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -30,7 +30,7 @@ var _rtmpConnection net.Conn
|
||||||
var _setStreamAsConnected func()
|
var _setStreamAsConnected func()
|
||||||
var _setBroadcaster func(models.Broadcaster)
|
var _setBroadcaster func(models.Broadcaster)
|
||||||
|
|
||||||
//Start starts the rtmp service, listening on port 1935
|
// Start starts the rtmp service, listening on port 1935.
|
||||||
func Start(setStreamAsConnected func(), setBroadcaster func(models.Broadcaster)) {
|
func Start(setStreamAsConnected func(), setBroadcaster func(models.Broadcaster)) {
|
||||||
_setStreamAsConnected = setStreamAsConnected
|
_setStreamAsConnected = setStreamAsConnected
|
||||||
_setBroadcaster = setBroadcaster
|
_setBroadcaster = setBroadcaster
|
||||||
|
|
|
@ -46,7 +46,7 @@ func setupStats() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//IsStreamConnected checks if the stream is connected or not
|
// IsStreamConnected checks if the stream is connected or not.
|
||||||
func IsStreamConnected() bool {
|
func IsStreamConnected() bool {
|
||||||
if !_stats.StreamConnected {
|
if !_stats.StreamConnected {
|
||||||
return false
|
return false
|
||||||
|
@ -62,7 +62,7 @@ func IsStreamConnected() bool {
|
||||||
return _stats.StreamConnected
|
return _stats.StreamConnected
|
||||||
}
|
}
|
||||||
|
|
||||||
//SetClientActive sets a client as active and connected
|
// SetClientActive sets a client as active and connected.
|
||||||
func SetClientActive(client models.Client) {
|
func SetClientActive(client models.Client) {
|
||||||
l.Lock()
|
l.Lock()
|
||||||
// If this clientID already exists then update it.
|
// If this clientID already exists then update it.
|
||||||
|
@ -88,7 +88,7 @@ func SetClientActive(client models.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//RemoveClient removes a client from the active clients record
|
// RemoveClient removes a client from the active clients record.
|
||||||
func RemoveClient(clientID string) {
|
func RemoveClient(clientID string) {
|
||||||
log.Trace("Removing the client:", clientID)
|
log.Trace("Removing the client:", clientID)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"github.com/owncast/owncast/models"
|
"github.com/owncast/owncast/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
//GetStatus gets the status of the system
|
// GetStatus gets the status of the system.
|
||||||
func GetStatus() models.Status {
|
func GetStatus() models.Status {
|
||||||
if _stats == nil {
|
if _stats == nil {
|
||||||
return models.Status{}
|
return models.Status{}
|
||||||
|
@ -22,7 +22,7 @@ func GetStatus() models.Status {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setBroadcaster will store the current inbound broadcasting details
|
// setBroadcaster will store the current inbound broadcasting details.
|
||||||
func setBroadcaster(broadcaster models.Broadcaster) {
|
func setBroadcaster(broadcaster models.Broadcaster) {
|
||||||
_broadcaster = &broadcaster
|
_broadcaster = &broadcaster
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ type LocalStorage struct {
|
||||||
// Cleanup old public HLS content every N min from the webroot.
|
// Cleanup old public HLS content every N min from the webroot.
|
||||||
var _onlineCleanupTicker *time.Ticker
|
var _onlineCleanupTicker *time.Ticker
|
||||||
|
|
||||||
// Setup configures this storage provider
|
// Setup configures this storage provider.
|
||||||
func (s *LocalStorage) Setup() error {
|
func (s *LocalStorage) Setup() error {
|
||||||
// NOTE: This cleanup timer will have to be disabled to support recordings in the future
|
// NOTE: This cleanup timer will have to be disabled to support recordings in the future
|
||||||
// as all HLS segments have to be publicly available on disk to keep a recording of them.
|
// as all HLS segments have to be publicly available on disk to keep a recording of them.
|
||||||
|
@ -33,12 +33,12 @@ func (s *LocalStorage) Setup() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SegmentWritten is called when a single segment of video is written
|
// SegmentWritten is called when a single segment of video is written.
|
||||||
func (s *LocalStorage) SegmentWritten(localFilePath string) {
|
func (s *LocalStorage) SegmentWritten(localFilePath string) {
|
||||||
s.Save(localFilePath, 0)
|
s.Save(localFilePath, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VariantPlaylistWritten is called when a variant hls playlist is written
|
// VariantPlaylistWritten is called when a variant hls playlist is written.
|
||||||
func (s *LocalStorage) VariantPlaylistWritten(localFilePath string) {
|
func (s *LocalStorage) VariantPlaylistWritten(localFilePath string) {
|
||||||
_, err := s.Save(localFilePath, 0)
|
_, err := s.Save(localFilePath, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -47,12 +47,12 @@ func (s *LocalStorage) VariantPlaylistWritten(localFilePath string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MasterPlaylistWritten is called when the master hls playlist is written
|
// MasterPlaylistWritten is called when the master hls playlist is written.
|
||||||
func (s *LocalStorage) MasterPlaylistWritten(localFilePath string) {
|
func (s *LocalStorage) MasterPlaylistWritten(localFilePath string) {
|
||||||
s.Save(localFilePath, 0)
|
s.Save(localFilePath, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save will save a local filepath using the storage provider
|
// Save will save a local filepath using the storage provider.
|
||||||
func (s *LocalStorage) Save(filePath string, retryCount int) (string, error) {
|
func (s *LocalStorage) Save(filePath string, retryCount int) (string, error) {
|
||||||
newPath := ""
|
newPath := ""
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ import (
|
||||||
// then keep a reference to it here.
|
// then keep a reference to it here.
|
||||||
var _queuedPlaylistUpdates = make(map[string]string, 0)
|
var _queuedPlaylistUpdates = make(map[string]string, 0)
|
||||||
|
|
||||||
//S3Storage is the s3 implementation of the ChunkStorageProvider
|
// S3Storage is the s3 implementation of the ChunkStorageProvider.
|
||||||
type S3Storage struct {
|
type S3Storage struct {
|
||||||
sess *session.Session
|
sess *session.Session
|
||||||
host string
|
host string
|
||||||
|
@ -40,7 +40,7 @@ type S3Storage struct {
|
||||||
|
|
||||||
var _uploader *s3manager.Uploader
|
var _uploader *s3manager.Uploader
|
||||||
|
|
||||||
//Setup sets up the s3 storage for saving the video to s3
|
// Setup sets up the s3 storage for saving the video to s3.
|
||||||
func (s *S3Storage) Setup() error {
|
func (s *S3Storage) Setup() error {
|
||||||
log.Trace("Setting up S3 for external storage of video...")
|
log.Trace("Setting up S3 for external storage of video...")
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ func (s *S3Storage) Setup() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SegmentWritten is called when a single segment of video is written
|
// SegmentWritten is called when a single segment of video is written.
|
||||||
func (s *S3Storage) SegmentWritten(localFilePath string) {
|
func (s *S3Storage) SegmentWritten(localFilePath string) {
|
||||||
index := utils.GetIndexFromFilePath(localFilePath)
|
index := utils.GetIndexFromFilePath(localFilePath)
|
||||||
performanceMonitorKey := "s3upload-" + index
|
performanceMonitorKey := "s3upload-" + index
|
||||||
|
@ -100,7 +100,7 @@ func (s *S3Storage) SegmentWritten(localFilePath string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VariantPlaylistWritten is called when a variant hls playlist is written
|
// VariantPlaylistWritten is called when a variant hls playlist is written.
|
||||||
func (s *S3Storage) VariantPlaylistWritten(localFilePath string) {
|
func (s *S3Storage) VariantPlaylistWritten(localFilePath string) {
|
||||||
// We are uploading the variant playlist after uploading the segment
|
// We are uploading the variant playlist after uploading the segment
|
||||||
// to make sure we're not referring to files in a playlist that don't
|
// to make sure we're not referring to files in a playlist that don't
|
||||||
|
@ -115,13 +115,13 @@ func (s *S3Storage) VariantPlaylistWritten(localFilePath string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MasterPlaylistWritten is called when the master hls playlist is written
|
// MasterPlaylistWritten is called when the master hls playlist is written.
|
||||||
func (s *S3Storage) MasterPlaylistWritten(localFilePath string) {
|
func (s *S3Storage) MasterPlaylistWritten(localFilePath string) {
|
||||||
// Rewrite the playlist to use absolute remote S3 URLs
|
// Rewrite the playlist to use absolute remote S3 URLs
|
||||||
s.rewriteRemotePlaylist(localFilePath)
|
s.rewriteRemotePlaylist(localFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save saves the file to the s3 bucket
|
// Save saves the file to the s3 bucket.
|
||||||
func (s *S3Storage) Save(filePath string, retryCount int) (string, error) {
|
func (s *S3Storage) Save(filePath string, retryCount int) (string, error) {
|
||||||
file, err := os.Open(filePath)
|
file, err := os.Open(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -23,7 +23,7 @@ var _offlineCleanupTimer *time.Timer
|
||||||
// While a stream takes place cleanup old HLS content every N min.
|
// While a stream takes place cleanup old HLS content every N min.
|
||||||
var _onlineCleanupTicker *time.Ticker
|
var _onlineCleanupTicker *time.Ticker
|
||||||
|
|
||||||
//setStreamAsConnected sets the stream as connected
|
// setStreamAsConnected sets the stream as connected.
|
||||||
func setStreamAsConnected() {
|
func setStreamAsConnected() {
|
||||||
_stats.StreamConnected = true
|
_stats.StreamConnected = true
|
||||||
_stats.LastConnectTime = utils.NullTime{time.Now(), true}
|
_stats.LastConnectTime = utils.NullTime{time.Now(), true}
|
||||||
|
@ -53,7 +53,7 @@ func setStreamAsConnected() {
|
||||||
ffmpeg.StartThumbnailGenerator(segmentPath, config.Config.VideoSettings.HighestQualityStreamIndex)
|
ffmpeg.StartThumbnailGenerator(segmentPath, config.Config.VideoSettings.HighestQualityStreamIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
//SetStreamAsDisconnected sets the stream as disconnected.
|
// SetStreamAsDisconnected sets the stream as disconnected.
|
||||||
func SetStreamAsDisconnected() {
|
func SetStreamAsDisconnected() {
|
||||||
_stats.StreamConnected = false
|
_stats.StreamConnected = false
|
||||||
_stats.LastDisconnectTime = utils.NullTime{time.Now(), true}
|
_stats.LastDisconnectTime = utils.NullTime{time.Now(), true}
|
||||||
|
@ -125,7 +125,7 @@ func SetStreamAsDisconnected() {
|
||||||
stopOnlineCleanupTimer()
|
stopOnlineCleanupTimer()
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartOfflineCleanupTimer will fire a cleanup after n minutes being disconnected
|
// StartOfflineCleanupTimer will fire a cleanup after n minutes being disconnected.
|
||||||
func StartOfflineCleanupTimer() {
|
func StartOfflineCleanupTimer() {
|
||||||
_offlineCleanupTimer = time.NewTimer(5 * time.Minute)
|
_offlineCleanupTimer = time.NewTimer(5 * time.Minute)
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -141,7 +141,7 @@ func StartOfflineCleanupTimer() {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopOfflineCleanupTimer will stop the previous cleanup timer
|
// StopOfflineCleanupTimer will stop the previous cleanup timer.
|
||||||
func StopOfflineCleanupTimer() {
|
func StopOfflineCleanupTimer() {
|
||||||
if _offlineCleanupTimer != nil {
|
if _offlineCleanupTimer != nil {
|
||||||
_offlineCleanupTimer.Stop()
|
_offlineCleanupTimer.Stop()
|
||||||
|
|
|
@ -15,7 +15,7 @@ import (
|
||||||
var _geoIPCache = map[string]GeoDetails{}
|
var _geoIPCache = map[string]GeoDetails{}
|
||||||
var _enabled = true // Try to use GeoIP support it by default.
|
var _enabled = true // Try to use GeoIP support it by default.
|
||||||
|
|
||||||
// GeoDetails stores details about a location
|
// GeoDetails stores details about a location.
|
||||||
type GeoDetails struct {
|
type GeoDetails struct {
|
||||||
CountryCode string `json:"countryCode"`
|
CountryCode string `json:"countryCode"`
|
||||||
RegionName string `json:"regionName"`
|
RegionName string `json:"regionName"`
|
||||||
|
|
|
@ -20,7 +20,7 @@ type OCLogger struct {
|
||||||
|
|
||||||
var Logger *OCLogger
|
var Logger *OCLogger
|
||||||
|
|
||||||
// Setup configures our custom logging destinations
|
// Setup configures our custom logging destinations.
|
||||||
func Setup() {
|
func Setup() {
|
||||||
logger.SetOutput(os.Stdout) // Send all logs to console
|
logger.SetOutput(os.Stdout) // Send all logs to console
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ func Setup() {
|
||||||
Logger = _logger
|
Logger = _logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fire runs for every logging request
|
// Fire runs for every logging request.
|
||||||
func (l *OCLogger) Fire(e *logger.Entry) error {
|
func (l *OCLogger) Fire(e *logger.Entry) error {
|
||||||
// Store all log messages to return back in the logging API
|
// Store all log messages to return back in the logging API
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
|
@ -44,7 +44,7 @@ func (l *OCLogger) Fire(e *logger.Entry) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Levels specifies what log levels we care about
|
// Levels specifies what log levels we care about.
|
||||||
func (l *OCLogger) Levels() []logrus.Level {
|
func (l *OCLogger) Levels() []logrus.Level {
|
||||||
return logrus.AllLevels
|
return logrus.AllLevels
|
||||||
}
|
}
|
||||||
|
|
10
main.go
10
main.go
|
@ -16,13 +16,13 @@ import (
|
||||||
"github.com/owncast/owncast/router"
|
"github.com/owncast/owncast/router"
|
||||||
)
|
)
|
||||||
|
|
||||||
// the following are injected at build-time
|
// the following are injected at build-time.
|
||||||
var (
|
var (
|
||||||
//GitCommit is the commit which this version of owncast is running
|
// GitCommit is the commit which this version of owncast is running.
|
||||||
GitCommit = "unknown"
|
GitCommit = "unknown"
|
||||||
//BuildVersion is the version
|
// BuildVersion is the version.
|
||||||
BuildVersion = "0.0.0"
|
BuildVersion = "0.0.0"
|
||||||
//BuildType is the type of build
|
// BuildType is the type of build.
|
||||||
BuildType = "localdev"
|
BuildType = "localdev"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//getReleaseString gets the version string
|
// getReleaseString gets the version string.
|
||||||
func getReleaseString() string {
|
func getReleaseString() string {
|
||||||
return fmt.Sprintf("Owncast v%s-%s (%s)", BuildVersion, BuildType, GitCommit)
|
return fmt.Sprintf("Owncast v%s-%s (%s)", BuildVersion, BuildType, GitCommit)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// How often we poll for updates
|
// How often we poll for updates.
|
||||||
const metricsPollingInterval = 1 * time.Minute
|
const metricsPollingInterval = 1 * time.Minute
|
||||||
|
|
||||||
// CollectedMetrics stores different collected + timestamped values
|
// CollectedMetrics stores different collected + timestamped values.
|
||||||
type CollectedMetrics struct {
|
type CollectedMetrics struct {
|
||||||
CPUUtilizations []timestampedValue `json:"cpu"`
|
CPUUtilizations []timestampedValue `json:"cpu"`
|
||||||
RAMUtilizations []timestampedValue `json:"memory"`
|
RAMUtilizations []timestampedValue `json:"memory"`
|
||||||
|
@ -16,10 +16,10 @@ type CollectedMetrics struct {
|
||||||
Viewers []timestampedValue `json:"-"`
|
Viewers []timestampedValue `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metrics is the shared Metrics instance
|
// Metrics is the shared Metrics instance.
|
||||||
var Metrics *CollectedMetrics
|
var Metrics *CollectedMetrics
|
||||||
|
|
||||||
// Start will begin the metrics collection and alerting
|
// Start will begin the metrics collection and alerting.
|
||||||
func Start() {
|
func Start() {
|
||||||
Metrics = new(CollectedMetrics)
|
Metrics = new(CollectedMetrics)
|
||||||
go startViewerCollectionMetrics()
|
go startViewerCollectionMetrics()
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/owncast/owncast/core"
|
"github.com/owncast/owncast/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// How often we poll for updates
|
// How often we poll for updates.
|
||||||
const viewerMetricsPollingInterval = 5 * time.Minute
|
const viewerMetricsPollingInterval = 5 * time.Minute
|
||||||
|
|
||||||
func startViewerCollectionMetrics() {
|
func startViewerCollectionMetrics() {
|
||||||
|
|
|
@ -20,7 +20,7 @@ type InboundStreamDetails struct {
|
||||||
Encoder string `json:"encoder"`
|
Encoder string `json:"encoder"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTMPStreamMetadata is the raw metadata that comes in with a RTMP connection
|
// RTMPStreamMetadata is the raw metadata that comes in with a RTMP connection.
|
||||||
type RTMPStreamMetadata struct {
|
type RTMPStreamMetadata struct {
|
||||||
Width int `json:"width"`
|
Width int `json:"width"`
|
||||||
Height int `json:"height"`
|
Height int `json:"height"`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
//ChatListener represents the listener for the chat server
|
// ChatListener represents the listener for the chat server.
|
||||||
type ChatListener interface {
|
type ChatListener interface {
|
||||||
ClientAdded(client Client)
|
ClientAdded(client Client)
|
||||||
ClientRemoved(clientID string)
|
ClientRemoved(clientID string)
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"mvdan.cc/xurls"
|
"mvdan.cc/xurls"
|
||||||
)
|
)
|
||||||
|
|
||||||
//ChatMessage represents a single chat message
|
// ChatMessage represents a single chat message.
|
||||||
type ChatMessage struct {
|
type ChatMessage struct {
|
||||||
ClientID string `json:"-"`
|
ClientID string `json:"-"`
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ type ChatMessage struct {
|
||||||
Timestamp time.Time `json:"timestamp"`
|
Timestamp time.Time `json:"timestamp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//Valid checks to ensure the message is valid
|
// Valid checks to ensure the message is valid.
|
||||||
func (m ChatMessage) Valid() bool {
|
func (m ChatMessage) Valid() bool {
|
||||||
return m.Author != "" && m.Body != "" && m.ID != ""
|
return m.Author != "" && m.Body != "" && m.ID != ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
//CustomEmoji represents an image that can be used in chat as a custom emoji
|
// CustomEmoji represents an image that can be used in chat as a custom emoji.
|
||||||
type CustomEmoji struct {
|
type CustomEmoji struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Emoji string `json:"emoji"`
|
Emoji string `json:"emoji"`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
//NameChangeEvent represents a user changing their name in chat
|
// NameChangeEvent represents a user changing their name in chat.
|
||||||
type NameChangeEvent struct {
|
type NameChangeEvent struct {
|
||||||
OldName string `json:"oldName"`
|
OldName string `json:"oldName"`
|
||||||
NewName string `json:"newName"`
|
NewName string `json:"newName"`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
//PingMessage represents a ping message between the client and server
|
// PingMessage represents a ping message between the client and server.
|
||||||
type PingMessage struct {
|
type PingMessage struct {
|
||||||
MessageType string `json:"type"`
|
MessageType string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
//Segment represents a segment of the live stream
|
// Segment represents a segment of the live stream.
|
||||||
type Segment struct {
|
type Segment struct {
|
||||||
VariantIndex int // The bitrate variant
|
VariantIndex int // The bitrate variant
|
||||||
FullDiskPath string // Where it lives on disk
|
FullDiskPath string // Where it lives on disk
|
||||||
|
@ -8,13 +8,13 @@ type Segment struct {
|
||||||
RemoteURL string
|
RemoteURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
//Variant represents a single video variant and the segments that make it up
|
// Variant represents a single video variant and the segments that make it up.
|
||||||
type Variant struct {
|
type Variant struct {
|
||||||
VariantIndex int
|
VariantIndex int
|
||||||
Segments map[string]*Segment
|
Segments map[string]*Segment
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetSegmentForFilename gets the segment for the provided filename
|
// GetSegmentForFilename gets the segment for the provided filename.
|
||||||
func (v *Variant) GetSegmentForFilename(filename string) *Segment {
|
func (v *Variant) GetSegmentForFilename(filename string) *Segment {
|
||||||
return v.Segments[filename]
|
return v.Segments[filename]
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"github.com/owncast/owncast/utils"
|
"github.com/owncast/owncast/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Stats holds the stats for the system
|
// Stats holds the stats for the system.
|
||||||
type Stats struct {
|
type Stats struct {
|
||||||
SessionMaxViewerCount int `json:"sessionMaxViewerCount"`
|
SessionMaxViewerCount int `json:"sessionMaxViewerCount"`
|
||||||
OverallMaxViewerCount int `json:"overallMaxViewerCount"`
|
OverallMaxViewerCount int `json:"overallMaxViewerCount"`
|
||||||
|
|
|
@ -2,7 +2,7 @@ package models
|
||||||
|
|
||||||
import "github.com/owncast/owncast/utils"
|
import "github.com/owncast/owncast/utils"
|
||||||
|
|
||||||
//Status represents the status of the system
|
// Status represents the status of the system.
|
||||||
type Status struct {
|
type Status struct {
|
||||||
Online bool `json:"online"`
|
Online bool `json:"online"`
|
||||||
ViewerCount int `json:"viewerCount"`
|
ViewerCount int `json:"viewerCount"`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
//StorageProvider is how a chunk storage provider should be implemented
|
// StorageProvider is how a chunk storage provider should be implemented.
|
||||||
type StorageProvider interface {
|
type StorageProvider interface {
|
||||||
Setup() error
|
Setup() error
|
||||||
Save(filePath string, retryCount int) (string, error)
|
Save(filePath string, retryCount int) (string, error)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/owncast/owncast/utils"
|
"github.com/owncast/owncast/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
//DisableCache writes the disable cache header on the responses
|
// DisableCache writes the disable cache header on the responses.
|
||||||
func DisableCache(w http.ResponseWriter) {
|
func DisableCache(w http.ResponseWriter) {
|
||||||
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
|
||||||
w.Header().Set("Expires", "Thu, 1 Jan 1970 00:00:00 GMT")
|
w.Header().Set("Expires", "Thu, 1 Jan 1970 00:00:00 GMT")
|
||||||
|
@ -21,7 +21,7 @@ func setCacheSeconds(seconds int, w http.ResponseWriter) {
|
||||||
w.Header().Set("Cache-Control", "public, max-age="+secondsStr)
|
w.Header().Set("Cache-Control", "public, max-age="+secondsStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessEtags gets and sets ETags for caching purposes
|
// ProcessEtags gets and sets ETags for caching purposes.
|
||||||
func ProcessEtags(w http.ResponseWriter, r *http.Request) int {
|
func ProcessEtags(w http.ResponseWriter, r *http.Request) int {
|
||||||
info, err := os.Stat(filepath.Join("webroot", r.URL.Path))
|
info, err := os.Stat(filepath.Join("webroot", r.URL.Path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -40,7 +40,7 @@ func ProcessEtags(w http.ResponseWriter, r *http.Request) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCachingHeaders will set the cache control header of a response
|
// SetCachingHeaders will set the cache control header of a response.
|
||||||
func SetCachingHeaders(w http.ResponseWriter, r *http.Request) {
|
func SetCachingHeaders(w http.ResponseWriter, r *http.Request) {
|
||||||
setCacheSeconds(utils.GetCacheDurationSecondsForPath(r.URL.Path), w)
|
setCacheSeconds(utils.GetCacheDurationSecondsForPath(r.URL.Path), w)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
//EnableCors enables the cors header on the responses
|
// EnableCors enables the cors header on the responses.
|
||||||
func EnableCors(w *http.ResponseWriter) {
|
func EnableCors(w *http.ResponseWriter) {
|
||||||
(*w).Header().Set("Access-Control-Allow-Origin", "*")
|
(*w).Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"github.com/owncast/owncast/yp"
|
"github.com/owncast/owncast/yp"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Start starts the router for the http, ws, and rtmp
|
// Start starts the router for the http, ws, and rtmp.
|
||||||
func Start() error {
|
func Start() error {
|
||||||
// static files
|
// static files
|
||||||
http.HandleFunc("/", controllers.IndexHandler)
|
http.HandleFunc("/", controllers.IndexHandler)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
//GenerateClientIDFromRequest generates a client id from the provided request
|
// GenerateClientIDFromRequest generates a client id from the provided request.
|
||||||
func GenerateClientIDFromRequest(req *http.Request) string {
|
func GenerateClientIDFromRequest(req *http.Request) string {
|
||||||
ipAddress := GetIPAddressFromRequest(req)
|
ipAddress := GetIPAddressFromRequest(req)
|
||||||
ipAddressComponents := strings.Split(ipAddress, ":")
|
ipAddressComponents := strings.Split(ipAddress, ":")
|
||||||
|
@ -23,7 +23,7 @@ func GenerateClientIDFromRequest(req *http.Request) string {
|
||||||
return hex.EncodeToString(hasher.Sum(nil))
|
return hex.EncodeToString(hasher.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetIPAddressFromRequest returns the IP address from a http request
|
// GetIPAddressFromRequest returns the IP address from a http request.
|
||||||
func GetIPAddressFromRequest(req *http.Request) string {
|
func GetIPAddressFromRequest(req *http.Request) string {
|
||||||
ipAddressString := req.RemoteAddr
|
ipAddressString := req.RemoteAddr
|
||||||
xForwardedFor := req.Header.Get("X-FORWARDED-FOR")
|
xForwardedFor := req.Header.Get("X-FORWARDED-FOR")
|
||||||
|
|
|
@ -5,13 +5,13 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The "start" timestamp of a timing event
|
// The "start" timestamp of a timing event.
|
||||||
var _pointsInTime = make(map[string]time.Time)
|
var _pointsInTime = make(map[string]time.Time)
|
||||||
|
|
||||||
// A collection of timestamp durations for returning the average of
|
// A collection of timestamp durations for returning the average of.
|
||||||
var _durationStorage = make(map[string][]float64)
|
var _durationStorage = make(map[string][]float64)
|
||||||
|
|
||||||
// StartPerformanceMonitor will keep track of the start time of this event
|
// StartPerformanceMonitor will keep track of the start time of this event.
|
||||||
func StartPerformanceMonitor(key string) {
|
func StartPerformanceMonitor(key string) {
|
||||||
if len(_durationStorage[key]) > 30 {
|
if len(_durationStorage[key]) > 30 {
|
||||||
_durationStorage[key] = removeHighAndLow(_durationStorage[key])
|
_durationStorage[key] = removeHighAndLow(_durationStorage[key])
|
||||||
|
@ -19,7 +19,7 @@ func StartPerformanceMonitor(key string) {
|
||||||
_pointsInTime[key] = time.Now()
|
_pointsInTime[key] = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAveragePerformance will return the average durations for the event
|
// GetAveragePerformance will return the average durations for the event.
|
||||||
func GetAveragePerformance(key string) float64 {
|
func GetAveragePerformance(key string) float64 {
|
||||||
timestamp := _pointsInTime[key]
|
timestamp := _pointsInTime[key]
|
||||||
if timestamp.IsZero() {
|
if timestamp.IsZero() {
|
||||||
|
|
|
@ -15,12 +15,12 @@ import (
|
||||||
"mvdan.cc/xurls"
|
"mvdan.cc/xurls"
|
||||||
)
|
)
|
||||||
|
|
||||||
//GetTemporaryPipePath gets the temporary path for the streampipe.flv file
|
// GetTemporaryPipePath gets the temporary path for the streampipe.flv file.
|
||||||
func GetTemporaryPipePath() string {
|
func GetTemporaryPipePath() string {
|
||||||
return filepath.Join(os.TempDir(), "streampipe.flv")
|
return filepath.Join(os.TempDir(), "streampipe.flv")
|
||||||
}
|
}
|
||||||
|
|
||||||
//DoesFileExists checks if the file exists
|
// DoesFileExists checks if the file exists.
|
||||||
func DoesFileExists(name string) bool {
|
func DoesFileExists(name string) bool {
|
||||||
if _, err := os.Stat(name); err != nil {
|
if _, err := os.Stat(name); err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
|
@ -31,7 +31,7 @@ func DoesFileExists(name string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetRelativePathFromAbsolutePath gets the relative path from the provided absolute path
|
// GetRelativePathFromAbsolutePath gets the relative path from the provided absolute path.
|
||||||
func GetRelativePathFromAbsolutePath(path string) string {
|
func GetRelativePathFromAbsolutePath(path string) string {
|
||||||
pathComponents := strings.Split(path, "/")
|
pathComponents := strings.Split(path, "/")
|
||||||
variant := pathComponents[len(pathComponents)-2]
|
variant := pathComponents[len(pathComponents)-2]
|
||||||
|
@ -47,7 +47,7 @@ func GetIndexFromFilePath(path string) string {
|
||||||
return variant
|
return variant
|
||||||
}
|
}
|
||||||
|
|
||||||
//Copy copies the file to destination
|
// Copy copies the file to destination.
|
||||||
func Copy(source, destination string) error {
|
func Copy(source, destination string) error {
|
||||||
input, err := ioutil.ReadFile(source)
|
input, err := ioutil.ReadFile(source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -57,12 +57,12 @@ func Copy(source, destination string) error {
|
||||||
return ioutil.WriteFile(destination, input, 0644)
|
return ioutil.WriteFile(destination, input, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Move moves the file to destination
|
// Move moves the file to destination.
|
||||||
func Move(source, destination string) error {
|
func Move(source, destination string) error {
|
||||||
return os.Rename(source, destination)
|
return os.Rename(source, destination)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsUserAgentABot returns if a web client user-agent is seen as a bot
|
// IsUserAgentABot returns if a web client user-agent is seen as a bot.
|
||||||
func IsUserAgentABot(userAgent string) bool {
|
func IsUserAgentABot(userAgent string) bool {
|
||||||
if userAgent == "" {
|
if userAgent == "" {
|
||||||
return false
|
return false
|
||||||
|
@ -111,7 +111,7 @@ func RenderSimpleMarkdown(raw string) string {
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCacheDurationSecondsForPath will return the number of seconds to cache an item
|
// GetCacheDurationSecondsForPath will return the number of seconds to cache an item.
|
||||||
func GetCacheDurationSecondsForPath(filePath string) int {
|
func GetCacheDurationSecondsForPath(filePath string) int {
|
||||||
if path.Base(filePath) == "thumbnail.jpg" {
|
if path.Base(filePath) == "thumbnail.jpg" {
|
||||||
// Thumbnails re-generate during live
|
// Thumbnails re-generate during live
|
||||||
|
|
|
@ -22,7 +22,7 @@ type ypDetailsResponse struct {
|
||||||
LastConnectTime utils.NullTime `json:"lastConnectTime"`
|
LastConnectTime utils.NullTime `json:"lastConnectTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetYPResponse gets the status of the server for YP purposes
|
// GetYPResponse gets the status of the server for YP purposes.
|
||||||
func GetYPResponse(w http.ResponseWriter, r *http.Request) {
|
func GetYPResponse(w http.ResponseWriter, r *http.Request) {
|
||||||
status := getStatus()
|
status := getStatus()
|
||||||
|
|
||||||
|
|
6
yp/yp.go
6
yp/yp.go
|
@ -38,13 +38,13 @@ type ypPingRequest struct {
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewYP creates a new instance of the YP service handler
|
// NewYP creates a new instance of the YP service handler.
|
||||||
func NewYP(getStatusFunc func() models.Status) *YP {
|
func NewYP(getStatusFunc func() models.Status) *YP {
|
||||||
getStatus = getStatusFunc
|
getStatus = getStatusFunc
|
||||||
return &YP{}
|
return &YP{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start is run when a live stream begins to start pinging YP
|
// Start is run when a live stream begins to start pinging YP.
|
||||||
func (yp *YP) Start() {
|
func (yp *YP) Start() {
|
||||||
yp.timer = time.NewTicker(pingInterval)
|
yp.timer = time.NewTicker(pingInterval)
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ func (yp *YP) Start() {
|
||||||
yp.ping()
|
yp.ping()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop stops the pinging of YP
|
// Stop stops the pinging of YP.
|
||||||
func (yp *YP) Stop() {
|
func (yp *YP) Stop() {
|
||||||
yp.timer.Stop()
|
yp.timer.Stop()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue