package icecast_output import ( "fmt" "io" "log" "git.icedream.tech/icedream/uplink/app/authentication" "git.icedream.tech/icedream/uplink/app/channels" "git.icedream.tech/icedream/uplink/app/servers/http" "git.icedream.tech/icedream/uplink/app/streams" "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 // TODO - handle channel and container closure } func (instance *pluginInstance) SetServer(server *httpserver.Server) { instance.server = server } func (instance *pluginInstance) Init() { router := instance.server.Router 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) if channel == nil { ctx.Status(404) return } 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.Header().Set("icy-name", "Channel name") // TODO ctx.Writer.Header().Set("icy-pub", "0") // TODO ctx.Writer.Header().Set("Server", "Uplink/0.0.0; Icecast 2.4.0 compatible") ctx.Writer.Header().Set("Cache-Control", "no-cache, no-store") ctx.Writer.Header().Set("Access-Control-Allow-Origin", "*") ctx.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type") ctx.Writer.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS, HEAD") ctx.Writer.WriteHeader(200) w := ctx.Writer var nw io.Writer = w sr := container.Sub() defer sr.Close() if sendMetadata { mw = streams.NewMetadataInjector(w, metaInt) nw = mw metadataChan := channel.Metadata() defer func() { metadataChan <- nil }() go func() { for metadata := range metadataChan { metadataToWrite := streams.Metadata{} if value, ok := metadata["StreamTitle"]; ok { metadataToWrite["StreamTitle"] = value } mw.SetMetadata(metadataToWrite) } }() } _, err := io.Copy(nw, sr) if err != nil { log.Println("copying stream to output failed:", err) } }) // TODO - output streams // TODO - dynamic transcoding targets }