2018-04-11 07:35:00 +00:00
|
|
|
package icecast_output
|
2018-04-10 15:51:03 +00:00
|
|
|
|
|
|
|
import (
|
2018-04-11 15:55:15 +00:00
|
|
|
"fmt"
|
2018-04-10 15:51:03 +00:00
|
|
|
"io"
|
2018-04-11 15:55:15 +00:00
|
|
|
"log"
|
2018-04-10 15:51:03 +00:00
|
|
|
|
|
|
|
"git.icedream.tech/icedream/uplink/app/authentication"
|
|
|
|
"git.icedream.tech/icedream/uplink/app/channels"
|
|
|
|
"git.icedream.tech/icedream/uplink/app/servers/http"
|
2018-04-11 15:55:15 +00:00
|
|
|
"git.icedream.tech/icedream/uplink/app/streams"
|
2018-04-10 15:51:03 +00:00
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
)
|
|
|
|
|
|
|
|
type pluginInstance struct {
|
|
|
|
server *httpserver.Server
|
|
|
|
authenticator authentication.Authenticator
|
|
|
|
channelManager *channels.ChannelManager
|
|
|
|
}
|
|
|
|
|
|
|
|
func (instance *pluginInstance) SetAuthenticator(authenticator authentication.Authenticator) {
|
|
|
|
instance.authenticator = authenticator
|
|
|
|
}
|
|
|
|
|
|
|
|
func (instance *pluginInstance) SetChannelManager(channelManager *channels.ChannelManager) {
|
|
|
|
instance.channelManager = channelManager
|
2018-04-11 15:55:15 +00:00
|
|
|
|
|
|
|
// TODO - handle channel and container closure
|
2018-04-10 15:51:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (instance *pluginInstance) SetServer(server *httpserver.Server) {
|
|
|
|
instance.server = server
|
2018-04-11 15:55:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (instance *pluginInstance) Init() {
|
2018-04-10 15:51:03 +00:00
|
|
|
router := instance.server.Router
|
|
|
|
|
2018-04-11 15:55:15 +00:00
|
|
|
router.GET("/:channel/:container", func(ctx *gin.Context) {
|
|
|
|
r := ctx.Request
|
|
|
|
var mw *streams.MetadataInjector
|
|
|
|
|
|
|
|
channelId := ctx.Param("channel")
|
|
|
|
containerId := ctx.Param("container")
|
|
|
|
sendMetadata := r.Header.Get("icy-metadata") == "1"
|
|
|
|
metaInt := 16 * 1024
|
|
|
|
|
|
|
|
channel := instance.channelManager.Channel(channelId)
|
2018-04-10 15:51:03 +00:00
|
|
|
if channel == nil {
|
|
|
|
ctx.Status(404)
|
|
|
|
return
|
|
|
|
}
|
2018-04-11 15:55:15 +00:00
|
|
|
|
|
|
|
container, ok := channel.OutputContainers[containerId]
|
|
|
|
if !ok {
|
|
|
|
ctx.Status(404)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.Writer.Header().Set("content-type", "audio/mpeg") // TODO
|
|
|
|
if sendMetadata {
|
|
|
|
ctx.Writer.Header().Set("icy-metadata", "1")
|
|
|
|
ctx.Writer.Header().Set("icy-metaint", fmt.Sprintf("%d", metaInt))
|
|
|
|
}
|
|
|
|
ctx.Writer.WriteHeader(200)
|
|
|
|
|
|
|
|
w := ctx.Writer
|
|
|
|
var nw io.Writer = w
|
|
|
|
|
|
|
|
sr := container.Sub()
|
|
|
|
defer sr.Close()
|
|
|
|
|
|
|
|
log.Println("Someone tuned in to", channelId, channel)
|
|
|
|
|
|
|
|
if sendMetadata {
|
|
|
|
mw = streams.NewMetadataInjector(w, metaInt)
|
|
|
|
nw = mw
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err := io.Copy(nw, sr)
|
|
|
|
if err != nil {
|
|
|
|
log.Println(err)
|
2018-04-10 15:51:03 +00:00
|
|
|
}
|
|
|
|
})
|
2018-04-11 15:55:15 +00:00
|
|
|
|
|
|
|
// TODO - output streams
|
|
|
|
// TODO - dynamic transcoding targets
|
2018-04-10 15:51:03 +00:00
|
|
|
}
|