add draft for rtmp

This commit is contained in:
Leandro Moreira
2024-05-12 15:05:35 -03:00
parent 4cb98061df
commit 199c23e9fd
23 changed files with 420 additions and 98 deletions

View File

@@ -2,6 +2,7 @@ package engine
import (
"fmt"
"strings"
"github.com/flavioribeiro/donut/internal/controllers/probers"
"github.com/flavioribeiro/donut/internal/controllers/streamers"
@@ -11,10 +12,10 @@ import (
)
type DonutEngine interface {
Appetizer() entities.DonutAppetizer
Appetizer() (entities.DonutAppetizer, error)
ServerIngredients() (*entities.StreamInfo, error)
ClientIngredients() (*entities.StreamInfo, error)
RecipeFor(server, client *entities.StreamInfo) *entities.DonutRecipe
RecipeFor(server, client *entities.StreamInfo) (*entities.DonutRecipe, error)
Serve(p *entities.DonutParameters)
}
@@ -80,7 +81,11 @@ type donutEngine struct {
}
func (d *donutEngine) ServerIngredients() (*entities.StreamInfo, error) {
return d.prober.StreamInfo(d.Appetizer())
appetizer, err := d.Appetizer()
if err != nil {
return nil, err
}
return d.prober.StreamInfo(appetizer)
}
func (d *donutEngine) ClientIngredients() (*entities.StreamInfo, error) {
@@ -91,7 +96,7 @@ func (d *donutEngine) Serve(p *entities.DonutParameters) {
d.streamer.Stream(p)
}
func (d *donutEngine) RecipeFor(server, client *entities.StreamInfo) *entities.DonutRecipe {
func (d *donutEngine) RecipeFor(server, client *entities.StreamInfo) (*entities.DonutRecipe, error) {
// TODO: implement proper matching
//
// suggestions:
@@ -101,10 +106,16 @@ func (d *donutEngine) RecipeFor(server, client *entities.StreamInfo) *entities.D
// preferable = [vp8, opus]
// if union(preferable, client.medias)
// transcode, preferable
appetizer, err := d.Appetizer()
if err != nil {
return nil, err
}
r := &entities.DonutRecipe{
Input: d.Appetizer(),
Input: appetizer,
Video: entities.DonutMediaTask{
Action: entities.DonutBypass,
// Action: entities.DonutBypass,
Action: entities.DonutTranscode,
Codec: entities.H264,
},
Audio: entities.DonutMediaTask{
@@ -122,18 +133,29 @@ func (d *donutEngine) RecipeFor(server, client *entities.StreamInfo) *entities.D
},
}
return r
return r, nil
}
func (d *donutEngine) Appetizer() entities.DonutAppetizer {
// TODO: implement input based on param to build proper SRT/RTMP/etc
return entities.DonutAppetizer{
URL: fmt.Sprintf("srt://%s:%d", d.req.SRTHost, d.req.SRTPort),
Format: "mpegts", // it'll change based on input, i.e. rmtp flv
Options: map[entities.DonutInputOptionKey]string{
entities.DonutSRTStreamID: d.req.SRTStreamID,
entities.DonutSRTTranstype: "live",
entities.DonutSRTsmoother: "live",
},
func (d *donutEngine) Appetizer() (entities.DonutAppetizer, error) {
if strings.Contains(strings.ToLower(d.req.StreamURL), "rtmp") {
return entities.DonutAppetizer{
URL: fmt.Sprintf("%s/%s", d.req.StreamURL, d.req.StreamID),
Options: map[entities.DonutInputOptionKey]string{
entities.DonutRTMPLive: "live",
},
// Format: "flv",
}, nil
} else if strings.Contains(strings.ToLower(d.req.StreamURL), "srt") {
return entities.DonutAppetizer{
URL: d.req.StreamURL,
Format: "mpegts", // TODO: check how to get format for srt
Options: map[entities.DonutInputOptionKey]string{
entities.DonutSRTStreamID: d.req.StreamID,
entities.DonutSRTTranstype: "live",
entities.DonutSRTsmoother: "live",
},
}, nil
}
return entities.DonutAppetizer{}, entities.ErrUnsupportedStreamURL
}