package api import ( "context" "fmt" "git.entr0py.de/garionion/gstreamer-graphix/gstreamer" "github.com/google/uuid" "github.com/rs/zerolog/log" "sync" "time" ) type PipelineService struct { UnimplementedPipelineServiceServer *gstreamer.Gstreamer Font, FontWeight string //default font FontSize int // Fontsize 0 does not make sense Context context.Context sync.RWMutex } func (s *PipelineService) UpdatePipeline(_ context.Context, updates *PipelineUpdates) (*PipelineUpdateResponse, error) { pipeline, err := s.Gstreamer.GetPipeline(updates.Id.GetId()) if err != nil { log.Error().Str("ID", updates.Id.GetId()).Err(err) } else { overlays := s.convertRPCOverlayToGstreamerOverlay(updates.GetOverlays()) pipeline.PipelineUpdates <- gstreamer.PipelineUpdates{Overlays: overlays} } return &PipelineUpdateResponse{PipelineId: &PipelineID{Id: updates.Id.GetId()}}, nil } func (s *PipelineService) StopPipeline(_ context.Context, id *PipelineID) (*PipelineStopResponse, error) { pipeline, err := s.Gstreamer.GetPipeline(id.GetId()) if err != nil { log.Error().Str("ID", id.GetId()).Err(err) } else { err = pipeline.Stop() } return &PipelineStopResponse{PipelineId: &PipelineID{Id: id.GetId()}}, err } func (s *PipelineService) StartPipeline(_ context.Context, id *PipelineID) (*PipelineStartResponse, error) { pipeline, err := s.Gstreamer.GetPipeline(id.GetId()) if err != nil { log.Error().Str("ID", id.GetId()).Err(err) } else { err = pipeline.Start() } return &PipelineStartResponse{PipelineId: &PipelineID{Id: id.GetId()}}, err } func (s *PipelineService) DeletePipeline(_ context.Context, id *PipelineID) (*PipelineDeleteResponse, error) { err := s.Gstreamer.DeletePipeline(id.GetId()) return &PipelineDeleteResponse{PipelineId: &PipelineID{Id: id.GetId()}}, err } func (s *PipelineService) CreatePipeline(_ context.Context, pipeline *Pipeline) (*PipelineCreationResponse, error) { uid, _ := uuid.NewRandom() id := uid.String() gstreamerPipeline := &gstreamer.Pipeline{ Name: pipeline.GetName(), ID: id, InputElement: gstreamer.InputElement{ Name: fmt.Sprintf("%s-input", pipeline.GetName()), Type: "filesrc", Properties: map[string]string{ "location": pipeline.GetClip(), }, }, OutputElement: gstreamer.OutputElement{ Name: fmt.Sprintf("%s-output", pipeline.GetName()), Type: pipeline.GetOutput(), }, } gstreamerPipeline.Overlays = s.convertRPCOverlayToGstreamerOverlay(pipeline.Overlays) _, err := gstreamerPipeline.Create() if err != nil { log.Error().Err(err) return nil, err } return &PipelineCreationResponse{ PipelineId: &PipelineID{Id: id}, }, nil } func (s *PipelineService) convertRPCOverlayToGstreamerOverlay(apiOverlays []*Overlay) map[string]gstreamer.Overlay { gstreamerOverlays := map[string]gstreamer.Overlay{} for _, overlay := range apiOverlays { switch overlay.GetOverlayData().(type) { case *Overlay_Extra: log.Error().Msgf("Extra Element not implemented, used by overlay %s", overlay.GetName()) case *Overlay_ImageOverlay: o := overlay.GetImageOverlay() imageOverlay := &gstreamer.ImageOverlay{ Name: overlay.GetName(), Path: o.GetPath(), X: int(overlay.GetX()), Y: int(overlay.GetY()), Display: overlay.GetDisplay(), BlendIn: time.Duration(overlay.GetBlendIn()), BlendOut: time.Duration(overlay.GetBlendOut()), } gstreamerOverlays[overlay.GetName()] = imageOverlay case *Overlay_TextOverlay: o := overlay.GetTextOverlay() if o.GetText() == "" { continue } font := s.Font if o.GetFontName() != "" { font = o.GetFontName() } fontsize := s.FontSize if o.GetFontSize() != 0 { fontsize = int(o.GetFontSize()) } fontweight := s.FontWeight if o.GetFontWeight() != "" { font = o.GetFontWeight() } textOverlay := &gstreamer.TextOverlay{ Name: overlay.GetName(), X: int(overlay.GetX()), Y: int(overlay.GetY()), Font: font, FontSize: fontsize, FontWeight: fontweight, Color: o.GetFontColor(), Value: o.GetText(), Display: overlay.GetDisplay(), MaxWidth: uint(o.GetMaxWidth()), BlendIn: time.Duration(overlay.GetBlendIn()), BlendOut: time.Duration(overlay.GetBlendOut()), } gstreamerOverlays[overlay.GetName()] = textOverlay } } return gstreamerOverlays }