0

Add endpoint for returning stream status

This commit is contained in:
Gabe Kangas 2020-06-02 00:27:54 -07:00
parent 020ace7ddd
commit 4cb282040b
3 changed files with 123 additions and 62 deletions

View File

@ -38,7 +38,6 @@ func (h *Handler) OnCreateStream(timestamp uint32, cmd *rtmpmsg.NetConnectionCre
func (h *Handler) OnPublish(timestamp uint32, cmd *rtmpmsg.NetStreamPublish) error { func (h *Handler) OnPublish(timestamp uint32, cmd *rtmpmsg.NetStreamPublish) error {
// log.Printf("OnPublish: %#v", cmd) // log.Printf("OnPublish: %#v", cmd)
log.Println("Incoming stream connected.") log.Println("Incoming stream connected.")
if cmd.PublishingName != configuration.VideoSettings.StreamingKey { if cmd.PublishingName != configuration.VideoSettings.StreamingKey {
@ -68,6 +67,8 @@ func (h *Handler) OnPublish(timestamp uint32, cmd *rtmpmsg.NetStreamPublish) err
go startFfmpeg(configuration) go startFfmpeg(configuration)
streamConnected()
return nil return nil
} }
@ -164,4 +165,6 @@ func (h *Handler) OnClose() {
if h.flvFile != nil { if h.flvFile != nil {
_ = h.flvFile.Close() _ = h.flvFile.Close()
} }
streamDisconnected()
} }

22
main.go
View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/json"
"net/http" "net/http"
"strconv" "strconv"
@ -10,6 +11,7 @@ import (
var ipfs icore.CoreAPI var ipfs icore.CoreAPI
var configuration = getConfig() var configuration = getConfig()
var online = false
func main() { func main() {
checkConfig(configuration) checkConfig(configuration)
@ -49,8 +51,28 @@ func startChatServer() {
// static files // static files
http.Handle("/", http.FileServer(http.Dir("webroot"))) http.Handle("/", http.FileServer(http.Dir("webroot")))
http.HandleFunc("/status", getStatus)
log.Printf("Starting public web server on port %d", configuration.WebServerPort) log.Printf("Starting public web server on port %d", configuration.WebServerPort)
log.Fatal(http.ListenAndServe(":"+strconv.Itoa(configuration.WebServerPort), nil)) log.Fatal(http.ListenAndServe(":"+strconv.Itoa(configuration.WebServerPort), nil))
} }
func getStatus(w http.ResponseWriter, r *http.Request) {
status := Status{
Online: online,
}
json.NewEncoder(w).Encode(status)
}
type Status struct {
Online bool `json:"online"`
}
func streamConnected() {
online = true
}
func streamDisconnected() {
online = false
}

View File

@ -6,6 +6,7 @@
href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css"
rel="stylesheet" rel="stylesheet"
/> />
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
@ -15,73 +16,78 @@
<script data-main="js/main" src="vendor/require.js"></script> <script data-main="js/main" src="vendor/require.js"></script>
</head> </head>
<div <div>
class="flex" <div class="flex">
> <div class="w-4/6">
<div class="w-4/6"> <video id="video" controls style="width: 100%;"></video>
<video id="video" controls style="width: 100%;"></video> <div id="app">
</div> {{ streamStatus }}
</div>
</div>
<div class="w-2/6"> <div class="w-2/6">
<div <div
id="messages-container" id="messages-container"
class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
style="height: 60vh; overflow-y: scroll;" style="height: 60vh; overflow-y: scroll;"
> >
<div data-bind="foreach: messages"> <div data-bind="foreach: messages">
<div class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"> <div class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
<div class="flex items-center"> <div class="flex items-center">
<img data-bind="attr:{src: image}" class="w-10 h-10 rounded-full mr-4 border-black-500" style="padding: 5px; background-color:#ececec;" /> <img
data-bind="attr:{src: image}"
class="w-10 h-10 rounded-full mr-4 border-black-500"
style="padding: 5px; background-color: #ececec;"
/>
<div class="text-sm"> <div class="text-sm">
<p class="text-700" data-bind="text:author"></p> <p class="text-700" data-bind="text:author"></p>
<p class="text-gray-600" data-bind="text:body"></p> <p class="text-gray-600" data-bind="text:body"></p>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<form
class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
data-bind="with: editingMessage"
>
<!-- Author -->
<label class="control-label" for="inputAuthor">Author</label>
<input
id="inputAuthor"
type="text"
data-bind="value: author"
class="appearance-none bg-gray-200 text-gray-700 border border-black-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white"
placeholder="Name"
/>
<!-- Body -->
<div>
<label class="control-label" for="inputBody">Message</label>
<div class="controls">
<textarea
id="inputBody"
data-bind="value: body"
placeholder="Message"
class="appearance-none block w-full bg-gray-200 text-gray-700 border border-black-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white"
>
</textarea>
</div>
</div>
<div class="control-group">
<div class="controls">
<a
href="#"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
data-bind="click: $parent.send.bind($parent)"
>Send</a
>
</div>
</div>
</form>
</div> </div>
<form
class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
data-bind="with: editingMessage"
>
<!-- Author -->
<label class="control-label" for="inputAuthor">Author</label>
<input
id="inputAuthor"
type="text"
data-bind="value: author"
class="appearance-none bg-gray-200 text-gray-700 border border-black-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white"
placeholder="Name"
/>
<!-- Body -->
<div>
<label class="control-label" for="inputBody">Message</label>
<div class="controls">
<textarea
id="inputBody"
data-bind="value: body"
placeholder="Message"
class="appearance-none block w-full bg-gray-200 text-gray-700 border border-black-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white"
>
</textarea>
</div>
</div>
<div class="control-group">
<div class="controls">
<a
href="#"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
data-bind="click: $parent.send.bind($parent)"
>Send</a
>
</div>
</div>
</form>
</div> </div>
</div> </div>
@ -116,3 +122,33 @@
}); });
} }
</script> </script>
<script>
var app = new Vue({
el: "#app",
data: {
streamStatus: "Hello Vue!",
},
});
</script>
<script>
setInterval(getStatus, 5000);
async function getStatus() {
let url = "/status";
try {
let response = await fetch(url);
let status = await response.json(); // read response body and parse as JSON
app.streamStatus = status.online
? "Stream is online."
: "Stream is offline.";
} catch(e) {
app.streamStatus = "Stream server is offline."
}
}
getStatus();
</script>