Rename "recoder" to "encoder"

This commit is contained in:
Dmitrii Okunev
2024-12-14 15:30:39 +00:00
parent 699b5847de
commit 8bc85e5dba
72 changed files with 1297 additions and 1279 deletions

View File

@@ -1 +1,24 @@
package adaptivesrt
import (
"context"
"fmt"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder"
)
type Encoder struct {
}
func NewEncoder(
ctx context.Context,
src string,
dst string,
) (*Encoder, error) {
proc, err := safeencoder.NewProcess(ctx)
if err != nil {
return nil, fmt.Errorf("unable to initialize an encoder: %w", err)
}
proc.NewEncoder()
}

View File

@@ -3,7 +3,7 @@ package livego
import (
"context"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder"
)
type Input struct {
@@ -12,7 +12,7 @@ type Input struct {
var _ recoder.Input = (*Input)(nil)
func (r *Recoder) NewInputFromURL(
func (r *Encoder) NewInputFromURL(
ctx context.Context,
url string,
cfg recoder.InputConfig,

View File

@@ -3,14 +3,14 @@ package livego
import (
"context"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder"
)
type Output struct {
URL string
}
func (r *Recoder) NewOutputFromURL(
func (r *Encoder) NewOutputFromURL(
ctx context.Context,
url string,
cfg recoder.OutputConfig,

View File

@@ -5,18 +5,18 @@ import (
"fmt"
"github.com/gwuhaolin/livego/protocol/rtmp/rtmprelay"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/xsync"
)
type Recoder struct {
type Encoder struct {
Locker xsync.Mutex
Relay *rtmprelay.RtmpRelay
}
var _ recoder.Recoder = (*Recoder)(nil)
var _ recoder.Encoder = (*Encoder)(nil)
func (r *Recoder) StartRecoding(
func (r *Encoder) StartRecoding(
ctx context.Context,
inputIface recoder.Input,
outputIface recoder.Output,
@@ -47,7 +47,7 @@ func (r *Recoder) StartRecoding(
})
}
func (r *Recoder) WaitForRecordingEnd(
func (r *Encoder) WaitForRecordingEnd(
ctx context.Context,
) error {
return xsync.DoR1(ctx, &r.Locker, func() error {
@@ -58,13 +58,13 @@ func (r *Recoder) WaitForRecordingEnd(
})
}
func (r *Recoder) GetStats(
func (r *Encoder) GetStats(
ctx context.Context,
) (*recoder.Stats, error) {
return &recoder.Stats{}, nil
}
func (r *Recoder) Close() error {
func (r *Encoder) Close() error {
ctx := context.TODO()
return xsync.DoR1(ctx, &r.Locker, func() error {
if r.Relay != nil {

View File

@@ -0,0 +1,19 @@
package livego
import (
"context"
"github.com/xaionaro-go/streamctl/pkg/encoder"
)
type EncoderFactory struct{}
var _ recoder.Factory = (*EncoderFactory)(nil)
func NewEncoderFactory() *EncoderFactory {
return &EncoderFactory{}
}
func (EncoderFactory) New(ctx context.Context, cfg recoder.Config) (recoder.Encoder, error) {
return &Encoder{}, nil
}

View File

@@ -1,3 +1,3 @@
package recoder
package encoder
type CodecName string

View File

@@ -1,3 +1,3 @@
package recoder
package encoder
type Config struct{}

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
type Decoder interface {
}

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
type HardwareDeviceTypeName string

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"context"
@@ -7,7 +7,7 @@ import (
"github.com/xaionaro-go/streamctl/pkg/streamserver/types"
)
type Recoder interface {
type Encoder interface {
io.Closer
NewInputFromURL(context.Context, string, string, InputConfig) (Input, error)
@@ -22,5 +22,5 @@ type NewInputFromPublisherer interface {
}
type Factory interface {
New(context.Context, Config) (Recoder, error)
New(context.Context, Config) (Encoder, error)
}

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"io"

View File

@@ -1,3 +1,3 @@
package recoder
package encoder
type InputConfig struct{}

View File

@@ -4,19 +4,19 @@ import (
"context"
"fmt"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder"
"github.com/xaionaro-go/streamctl/pkg/encoder"
saferecoder "github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder"
)
type Recoder struct {
*saferecoder.Recoder
type Encoder struct {
*saferecoder.Encoder
Process *saferecoder.Process
}
func (r *Recoder) StartRecoding(
func (r *Encoder) StartRecoding(
ctx context.Context,
inputIface recoder.Input,
outputIface recoder.Output,
inputIface encoder.Input,
outputIface encoder.Output,
) error {
input, ok := inputIface.(*saferecoder.Input)
if !ok {
@@ -26,34 +26,34 @@ func (r *Recoder) StartRecoding(
if !ok {
return fmt.Errorf("expected 'output' of type %T, but received %T", output, outputIface)
}
return r.Recoder.StartRecoding(ctx, input, output)
return r.Encoder.StartEncoding(ctx, input, output)
}
func (r *Recoder) NewInputFromURL(
func (r *Encoder) NewInputFromURL(
ctx context.Context,
url string,
authKey string,
cfg recoder.InputConfig,
) (recoder.Input, error) {
cfg encoder.InputConfig,
) (encoder.Input, error) {
return r.Process.NewInputFromURL(ctx, url, authKey, cfg)
}
func (r *Recoder) NewOutputFromURL(
func (r *Encoder) NewOutputFromURL(
ctx context.Context,
url string,
streamKey string,
cfg recoder.OutputConfig,
) (recoder.Output, error) {
cfg encoder.OutputConfig,
) (encoder.Output, error) {
return r.Process.NewOutputFromURL(ctx, url, streamKey, cfg)
}
func (r *Recoder) WaitForRecordingEnd(ctx context.Context) error {
return r.Recoder.Wait(ctx)
func (r *Encoder) WaitForRecordingEnd(ctx context.Context) error {
return r.Encoder.Wait(ctx)
}
func (r *Recoder) Close() error {
func (r *Encoder) Close() error {
err := r.Process.Kill()
r.Process = nil
r.Recoder = nil
r.Encoder = nil
return err
}

View File

@@ -11,7 +11,7 @@ import (
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/facebookincubator/go-belt/tool/logger/implementation/logrus"
"github.com/spf13/pflag"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/encoder"
)
func main() {
@@ -37,7 +37,7 @@ func main() {
fromURL := pflag.Arg(0)
toURL := pflag.Arg(1)
astiav.SetLogLevel(recoder.LogLevelToAstiav(l.Level()))
astiav.SetLogLevel(encoder.LogLevelToAstiav(l.Level()))
astiav.SetLogCallback(func(c astiav.Classer, level astiav.LogLevel, fmt, msg string) {
var cs string
if c != nil {
@@ -46,26 +46,26 @@ func main() {
}
}
l.Logf(
recoder.LogLevelFromAstiav(level),
encoder.LogLevelFromAstiav(level),
"%s%s",
strings.TrimSpace(msg), cs,
)
})
l.Debugf("opening '%s' as the input...", fromURL)
input, err := recoder.NewInputFromURL(ctx, fromURL, "", recoder.InputConfig{})
input, err := encoder.NewInputFromURL(ctx, fromURL, "", encoder.InputConfig{})
if err != nil {
l.Fatal(err)
}
l.Debugf("opening '%s' as the output...", toURL)
output, err := recoder.NewOutputFromURL(ctx, toURL, "", recoder.OutputConfig{})
output, err := encoder.NewOutputFromURL(ctx, toURL, "", encoder.OutputConfig{})
if err != nil {
l.Fatal(err)
}
l.Debugf("starting the recoding...")
err = recoder.New(recoder.RecoderConfig{}).Recode(ctx, input, output)
err = encoder.New(encoder.EncoderConfig{}).Recode(ctx, input, output)
if err != nil {
l.Fatal(err)
}

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"context"
@@ -10,10 +10,10 @@ import (
"github.com/asticode/go-astiav"
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder"
)
type DecoderConfig = recoder.DecoderConfig
type DecoderConfig = encoder.DecoderConfig
type Decoder struct {
Locker sync.Mutex

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"github.com/asticode/go-astiav"

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"context"

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"context"

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"context"
@@ -8,32 +8,32 @@ import (
"github.com/asticode/go-astiav"
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/encoder/types"
"github.com/xaionaro-go/streamctl/pkg/observability"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/recoder/types"
)
type RecoderConfig = recoder.Config
type EncoderConfig = encoder.Config
type Packet = types.Packet
type RecoderStats struct {
type EncoderStats struct {
BytesCountRead atomic.Uint64
BytesCountWrote atomic.Uint64
}
type Recoder struct {
type Encoder struct {
WaiterChan chan struct{}
Result error
RecoderConfig
RecoderStats
EncoderConfig
EncoderStats
}
func New(
cfg RecoderConfig,
) *Recoder {
result := &Recoder{
cfg EncoderConfig,
) *Encoder {
result := &Encoder{
WaiterChan: make(chan struct{}),
RecoderConfig: cfg,
EncoderConfig: cfg,
}
close(
result.WaiterChan,
@@ -41,7 +41,7 @@ func New(
return result
}
func (r *Recoder) StartRecoding(
func (r *Encoder) StartRecoding(
ctx context.Context,
input *Input,
output *Output,
@@ -138,7 +138,7 @@ func (r *Recoder) StartRecoding(
return nil
}
func (r *Recoder) Wait(ctx context.Context) error {
func (r *Encoder) Wait(ctx context.Context) error {
select {
case <-ctx.Done():
return ctx.Err()
@@ -147,7 +147,7 @@ func (r *Recoder) Wait(ctx context.Context) error {
return r.Result
}
func (r *Recoder) Recode(
func (r *Encoder) Recode(
ctx context.Context,
input *Input,
output *Output,

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"time"

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"context"
@@ -6,10 +6,10 @@ import (
"github.com/asticode/go-astiav"
"github.com/asticode/go-astikit"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder"
)
type InputConfig = recoder.InputConfig
type InputConfig = encoder.InputConfig
type Input struct {
*astikit.Closer

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"github.com/asticode/go-astiav"

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"context"
@@ -9,14 +9,14 @@ import (
"github.com/asticode/go-astiav"
"github.com/asticode/go-astikit"
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/observability"
"github.com/xaionaro-go/streamctl/pkg/proxy"
"github.com/xaionaro-go/streamctl/pkg/recoder"
)
const unwrapTLSViaProxy = false
type OutputConfig = recoder.OutputConfig
type OutputConfig = encoder.OutputConfig
type Output struct {
*astikit.Closer

View File

@@ -0,0 +1,37 @@
package libav
import (
"context"
"fmt"
"github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder"
)
type EncoderFactory struct{}
var _ encoder.Factory = (*EncoderFactory)(nil)
func NewEncoderFactory() *EncoderFactory {
return &EncoderFactory{}
}
func (EncoderFactory) New(
ctx context.Context,
cfg encoder.Config,
) (encoder.Encoder, error) {
process, err := safeencoder.NewProcess(ctx)
if err != nil {
return nil, fmt.Errorf("unable to initialize the process: %w", err)
}
recoderInstance, err := process.NewEncoder(cfg)
if err != nil {
return nil, fmt.Errorf("unable to initialize the recoder: %w", err)
}
return &Encoder{
Process: process,
Encoder: recoderInstance,
}, nil
}

View File

@@ -0,0 +1,78 @@
package safeencoder
import (
"context"
"fmt"
"github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/encoder/types"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/process"
)
type Packet = types.Packet
type EncoderID = process.EncoderID
type EncoderConfig = process.EncoderConfig
type Encoder struct {
Process *Process
ID EncoderID
}
func (p *Process) NewEncoder(
cfg EncoderConfig,
) (*Encoder, error) {
recoderID, err := p.processBackend.Client.NewEncoder(context.TODO(), cfg)
if err != nil {
return nil, err
}
return &Encoder{
Process: p,
ID: EncoderID(recoderID),
}, nil
}
func (r *Encoder) Encode(
ctx context.Context,
input *Input,
output *Output,
) error {
err := r.StartEncoding(ctx, input, output)
if err != nil {
return fmt.Errorf("got an error while starting the recording: %w", err)
}
if err != r.Wait(ctx) {
return fmt.Errorf("got an error while waiting for a completion: %w", err)
}
return nil
}
func (r *Encoder) StartEncoding(
ctx context.Context,
input *Input,
output *Output,
) error {
return r.Process.processBackend.Client.StartEncoding(
ctx,
r.ID,
input.ID,
output.ID,
)
}
type EncoderStats = encoder.Stats
func (r *Encoder) GetStats(ctx context.Context) (*EncoderStats, error) {
return r.Process.processBackend.Client.GetEncoderStats(ctx, r.ID)
}
func (r *Encoder) Wait(ctx context.Context) error {
ch, err := r.Process.Client.EncodingEndedChan(ctx, r.ID)
if err != nil {
return err
}
<-ch
return nil
}

View File

@@ -0,0 +1,5 @@
all: go
go:
protoc --go_out=. --go-grpc_out=. encoder.proto

View File

@@ -1,17 +1,17 @@
syntax = "proto3";
package recoder_grpc;
option go_package = "go/recoder_grpc";
package encoder_grpc;
option go_package = "go/encoder_grpc";
service Recoder {
service Encoder {
rpc SetLoggingLevel(SetLoggingLevelRequest) returns(SetLoggingLevelReply) {}
rpc NewInput(NewInputRequest) returns (NewInputReply) {}
rpc NewOutput(NewOutputRequest) returns (NewOutputReply) {}
rpc NewRecoder(NewRecoderRequest) returns (NewRecoderReply) {}
rpc NewEncoder(NewEncoderRequest) returns (NewEncoderReply) {}
rpc CloseInput(CloseInputRequest) returns (CloseInputReply) {}
rpc CloseOutput(CloseOutputRequest) returns (CloseOutputReply) {}
rpc GetRecoderStats(GetRecoderStatsRequest) returns (GetRecoderStatsReply) {}
rpc StartRecoding(StartRecodingRequest) returns (StartRecodingReply) {}
rpc RecodingEndedChan(RecodingEndedChanRequest) returns (stream RecodingEndedChanReply) {}
rpc GetEncoderStats(GetEncoderStatsRequest) returns (GetEncoderStatsReply) {}
rpc StartEncoding(StartEncodingRequest) returns (StartEncodingReply) {}
rpc EncodingEndedChan(EncodingEndedChanRequest) returns (stream EncodingEndedChanReply) {}
}
enum LoggingLevel {
@@ -69,13 +69,13 @@ message NewOutputReply {
uint64 id = 1;
}
message RecoderConfig {}
message EncoderConfig {}
message NewRecoderRequest {
RecoderConfig config = 1;
message NewEncoderRequest {
EncoderConfig config = 1;
}
message NewRecoderReply {
message NewEncoderReply {
uint64 id = 1;
}
@@ -88,23 +88,23 @@ message CloseOutputRequest {
}
message CloseOutputReply {}
message GetRecoderStatsRequest {
uint64 recoderID = 1;
message GetEncoderStatsRequest {
uint64 encoderID = 1;
}
message GetRecoderStatsReply {
message GetEncoderStatsReply {
uint64 bytesCountRead = 1;
uint64 bytesCountWrote = 2;
}
message StartRecodingRequest {
uint64 recoderID = 1;
message StartEncodingRequest {
uint64 encoderID = 1;
uint64 inputID = 2;
uint64 outputID = 3;
}
message StartRecodingReply {}
message StartEncodingReply {}
message RecodingEndedChanRequest {
uint64 recoderID = 1;
message EncodingEndedChanRequest {
uint64 encoderID = 1;
}
message RecodingEndedChanReply {}
message EncodingEndedChanReply {}

View File

@@ -0,0 +1,413 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package encoder_grpc
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion7
// EncoderClient is the client API for Encoder service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type EncoderClient interface {
SetLoggingLevel(ctx context.Context, in *SetLoggingLevelRequest, opts ...grpc.CallOption) (*SetLoggingLevelReply, error)
NewInput(ctx context.Context, in *NewInputRequest, opts ...grpc.CallOption) (*NewInputReply, error)
NewOutput(ctx context.Context, in *NewOutputRequest, opts ...grpc.CallOption) (*NewOutputReply, error)
NewEncoder(ctx context.Context, in *NewEncoderRequest, opts ...grpc.CallOption) (*NewEncoderReply, error)
CloseInput(ctx context.Context, in *CloseInputRequest, opts ...grpc.CallOption) (*CloseInputReply, error)
CloseOutput(ctx context.Context, in *CloseOutputRequest, opts ...grpc.CallOption) (*CloseOutputReply, error)
GetEncoderStats(ctx context.Context, in *GetEncoderStatsRequest, opts ...grpc.CallOption) (*GetEncoderStatsReply, error)
StartEncoding(ctx context.Context, in *StartEncodingRequest, opts ...grpc.CallOption) (*StartEncodingReply, error)
EncodingEndedChan(ctx context.Context, in *EncodingEndedChanRequest, opts ...grpc.CallOption) (Encoder_EncodingEndedChanClient, error)
}
type encoderClient struct {
cc grpc.ClientConnInterface
}
func NewEncoderClient(cc grpc.ClientConnInterface) EncoderClient {
return &encoderClient{cc}
}
func (c *encoderClient) SetLoggingLevel(ctx context.Context, in *SetLoggingLevelRequest, opts ...grpc.CallOption) (*SetLoggingLevelReply, error) {
out := new(SetLoggingLevelReply)
err := c.cc.Invoke(ctx, "/encoder_grpc.Encoder/SetLoggingLevel", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *encoderClient) NewInput(ctx context.Context, in *NewInputRequest, opts ...grpc.CallOption) (*NewInputReply, error) {
out := new(NewInputReply)
err := c.cc.Invoke(ctx, "/encoder_grpc.Encoder/NewInput", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *encoderClient) NewOutput(ctx context.Context, in *NewOutputRequest, opts ...grpc.CallOption) (*NewOutputReply, error) {
out := new(NewOutputReply)
err := c.cc.Invoke(ctx, "/encoder_grpc.Encoder/NewOutput", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *encoderClient) NewEncoder(ctx context.Context, in *NewEncoderRequest, opts ...grpc.CallOption) (*NewEncoderReply, error) {
out := new(NewEncoderReply)
err := c.cc.Invoke(ctx, "/encoder_grpc.Encoder/NewEncoder", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *encoderClient) CloseInput(ctx context.Context, in *CloseInputRequest, opts ...grpc.CallOption) (*CloseInputReply, error) {
out := new(CloseInputReply)
err := c.cc.Invoke(ctx, "/encoder_grpc.Encoder/CloseInput", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *encoderClient) CloseOutput(ctx context.Context, in *CloseOutputRequest, opts ...grpc.CallOption) (*CloseOutputReply, error) {
out := new(CloseOutputReply)
err := c.cc.Invoke(ctx, "/encoder_grpc.Encoder/CloseOutput", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *encoderClient) GetEncoderStats(ctx context.Context, in *GetEncoderStatsRequest, opts ...grpc.CallOption) (*GetEncoderStatsReply, error) {
out := new(GetEncoderStatsReply)
err := c.cc.Invoke(ctx, "/encoder_grpc.Encoder/GetEncoderStats", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *encoderClient) StartEncoding(ctx context.Context, in *StartEncodingRequest, opts ...grpc.CallOption) (*StartEncodingReply, error) {
out := new(StartEncodingReply)
err := c.cc.Invoke(ctx, "/encoder_grpc.Encoder/StartEncoding", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *encoderClient) EncodingEndedChan(ctx context.Context, in *EncodingEndedChanRequest, opts ...grpc.CallOption) (Encoder_EncodingEndedChanClient, error) {
stream, err := c.cc.NewStream(ctx, &_Encoder_serviceDesc.Streams[0], "/encoder_grpc.Encoder/EncodingEndedChan", opts...)
if err != nil {
return nil, err
}
x := &encoderEncodingEndedChanClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type Encoder_EncodingEndedChanClient interface {
Recv() (*EncodingEndedChanReply, error)
grpc.ClientStream
}
type encoderEncodingEndedChanClient struct {
grpc.ClientStream
}
func (x *encoderEncodingEndedChanClient) Recv() (*EncodingEndedChanReply, error) {
m := new(EncodingEndedChanReply)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// EncoderServer is the server API for Encoder service.
// All implementations must embed UnimplementedEncoderServer
// for forward compatibility
type EncoderServer interface {
SetLoggingLevel(context.Context, *SetLoggingLevelRequest) (*SetLoggingLevelReply, error)
NewInput(context.Context, *NewInputRequest) (*NewInputReply, error)
NewOutput(context.Context, *NewOutputRequest) (*NewOutputReply, error)
NewEncoder(context.Context, *NewEncoderRequest) (*NewEncoderReply, error)
CloseInput(context.Context, *CloseInputRequest) (*CloseInputReply, error)
CloseOutput(context.Context, *CloseOutputRequest) (*CloseOutputReply, error)
GetEncoderStats(context.Context, *GetEncoderStatsRequest) (*GetEncoderStatsReply, error)
StartEncoding(context.Context, *StartEncodingRequest) (*StartEncodingReply, error)
EncodingEndedChan(*EncodingEndedChanRequest, Encoder_EncodingEndedChanServer) error
mustEmbedUnimplementedEncoderServer()
}
// UnimplementedEncoderServer must be embedded to have forward compatible implementations.
type UnimplementedEncoderServer struct {
}
func (UnimplementedEncoderServer) SetLoggingLevel(context.Context, *SetLoggingLevelRequest) (*SetLoggingLevelReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetLoggingLevel not implemented")
}
func (UnimplementedEncoderServer) NewInput(context.Context, *NewInputRequest) (*NewInputReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method NewInput not implemented")
}
func (UnimplementedEncoderServer) NewOutput(context.Context, *NewOutputRequest) (*NewOutputReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method NewOutput not implemented")
}
func (UnimplementedEncoderServer) NewEncoder(context.Context, *NewEncoderRequest) (*NewEncoderReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method NewEncoder not implemented")
}
func (UnimplementedEncoderServer) CloseInput(context.Context, *CloseInputRequest) (*CloseInputReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method CloseInput not implemented")
}
func (UnimplementedEncoderServer) CloseOutput(context.Context, *CloseOutputRequest) (*CloseOutputReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method CloseOutput not implemented")
}
func (UnimplementedEncoderServer) GetEncoderStats(context.Context, *GetEncoderStatsRequest) (*GetEncoderStatsReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetEncoderStats not implemented")
}
func (UnimplementedEncoderServer) StartEncoding(context.Context, *StartEncodingRequest) (*StartEncodingReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method StartEncoding not implemented")
}
func (UnimplementedEncoderServer) EncodingEndedChan(*EncodingEndedChanRequest, Encoder_EncodingEndedChanServer) error {
return status.Errorf(codes.Unimplemented, "method EncodingEndedChan not implemented")
}
func (UnimplementedEncoderServer) mustEmbedUnimplementedEncoderServer() {}
// UnsafeEncoderServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to EncoderServer will
// result in compilation errors.
type UnsafeEncoderServer interface {
mustEmbedUnimplementedEncoderServer()
}
func RegisterEncoderServer(s *grpc.Server, srv EncoderServer) {
s.RegisterService(&_Encoder_serviceDesc, srv)
}
func _Encoder_SetLoggingLevel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SetLoggingLevelRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EncoderServer).SetLoggingLevel(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/encoder_grpc.Encoder/SetLoggingLevel",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EncoderServer).SetLoggingLevel(ctx, req.(*SetLoggingLevelRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Encoder_NewInput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NewInputRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EncoderServer).NewInput(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/encoder_grpc.Encoder/NewInput",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EncoderServer).NewInput(ctx, req.(*NewInputRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Encoder_NewOutput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NewOutputRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EncoderServer).NewOutput(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/encoder_grpc.Encoder/NewOutput",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EncoderServer).NewOutput(ctx, req.(*NewOutputRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Encoder_NewEncoder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NewEncoderRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EncoderServer).NewEncoder(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/encoder_grpc.Encoder/NewEncoder",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EncoderServer).NewEncoder(ctx, req.(*NewEncoderRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Encoder_CloseInput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CloseInputRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EncoderServer).CloseInput(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/encoder_grpc.Encoder/CloseInput",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EncoderServer).CloseInput(ctx, req.(*CloseInputRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Encoder_CloseOutput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CloseOutputRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EncoderServer).CloseOutput(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/encoder_grpc.Encoder/CloseOutput",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EncoderServer).CloseOutput(ctx, req.(*CloseOutputRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Encoder_GetEncoderStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetEncoderStatsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EncoderServer).GetEncoderStats(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/encoder_grpc.Encoder/GetEncoderStats",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EncoderServer).GetEncoderStats(ctx, req.(*GetEncoderStatsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Encoder_StartEncoding_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(StartEncodingRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(EncoderServer).StartEncoding(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/encoder_grpc.Encoder/StartEncoding",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(EncoderServer).StartEncoding(ctx, req.(*StartEncodingRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Encoder_EncodingEndedChan_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(EncodingEndedChanRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(EncoderServer).EncodingEndedChan(m, &encoderEncodingEndedChanServer{stream})
}
type Encoder_EncodingEndedChanServer interface {
Send(*EncodingEndedChanReply) error
grpc.ServerStream
}
type encoderEncodingEndedChanServer struct {
grpc.ServerStream
}
func (x *encoderEncodingEndedChanServer) Send(m *EncodingEndedChanReply) error {
return x.ServerStream.SendMsg(m)
}
var _Encoder_serviceDesc = grpc.ServiceDesc{
ServiceName: "encoder_grpc.Encoder",
HandlerType: (*EncoderServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SetLoggingLevel",
Handler: _Encoder_SetLoggingLevel_Handler,
},
{
MethodName: "NewInput",
Handler: _Encoder_NewInput_Handler,
},
{
MethodName: "NewOutput",
Handler: _Encoder_NewOutput_Handler,
},
{
MethodName: "NewEncoder",
Handler: _Encoder_NewEncoder_Handler,
},
{
MethodName: "CloseInput",
Handler: _Encoder_CloseInput_Handler,
},
{
MethodName: "CloseOutput",
Handler: _Encoder_CloseOutput_Handler,
},
{
MethodName: "GetEncoderStats",
Handler: _Encoder_GetEncoderStats_Handler,
},
{
MethodName: "StartEncoding",
Handler: _Encoder_StartEncoding_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "EncodingEndedChan",
Handler: _Encoder_EncodingEndedChan_Handler,
ServerStreams: true,
},
},
Metadata: "encoder.proto",
}

View File

@@ -1,9 +1,9 @@
package saferecoder
package safeencoder
import (
"context"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/process"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/process"
)
type InputID = process.InputID

View File

@@ -1,9 +1,9 @@
package saferecoder
package safeencoder
import (
"context"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/process"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/process"
)
type OutputID = process.OutputID

View File

@@ -1,13 +1,13 @@
package saferecoder
package safeencoder
import (
"context"
"fmt"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/process"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/process"
)
type processBackend = process.Recoder
type processBackend = process.Encoder
type Process struct {
*processBackend
}

View File

@@ -7,9 +7,9 @@ import (
"io"
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/grpc/go/encoder_grpc"
"github.com/xaionaro-go/streamctl/pkg/observability"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/grpc/go/recoder_grpc"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
@@ -22,7 +22,7 @@ func New(target string) *Client {
return &Client{Target: target}
}
func (c *Client) grpcClient() (recoder_grpc.RecoderClient, *grpc.ClientConn, error) {
func (c *Client) grpcClient() (encoder_grpc.EncoderClient, *grpc.ClientConn, error) {
conn, err := grpc.NewClient(
c.Target,
grpc.WithTransportCredentials(insecure.NewCredentials()),
@@ -31,7 +31,7 @@ func (c *Client) grpcClient() (recoder_grpc.RecoderClient, *grpc.ClientConn, err
return nil, nil, fmt.Errorf("unable to initialize a gRPC client: %w", err)
}
client := recoder_grpc.NewRecoderClient(conn)
client := encoder_grpc.NewEncoderClient(conn)
return client, conn, nil
}
@@ -45,7 +45,7 @@ func (c *Client) SetLoggingLevel(
}
defer conn.Close()
_, err = client.SetLoggingLevel(ctx, &recoder_grpc.SetLoggingLevelRequest{
_, err = client.SetLoggingLevel(ctx, &encoder_grpc.SetLoggingLevelRequest{
Level: logLevelGo2Protobuf(logLevel),
})
if err != nil {
@@ -54,7 +54,7 @@ func (c *Client) SetLoggingLevel(
return nil
}
type InputConfig = recoder.InputConfig
type InputConfig = encoder.InputConfig
type InputID uint64
func (c *Client) NewInputFromURL(
@@ -72,16 +72,16 @@ func (c *Client) NewInputFromURL(
logger.Debugf(ctx, "NewInputFromURL(ctx, '%s', authKey, %#+v)", url, authKey)
defer func() { logger.Debugf(ctx, "/NewInputFromURL(ctx, '%s', authKey, %#+v): %v", url, authKey, _err) }()
resp, err := client.NewInput(ctx, &recoder_grpc.NewInputRequest{
Path: &recoder_grpc.ResourcePath{
ResourcePath: &recoder_grpc.ResourcePath_Url{
Url: &recoder_grpc.ResourcePathURL{
resp, err := client.NewInput(ctx, &encoder_grpc.NewInputRequest{
Path: &encoder_grpc.ResourcePath{
ResourcePath: &encoder_grpc.ResourcePath_Url{
Url: &encoder_grpc.ResourcePathURL{
Url: url,
AuthKey: authKey,
},
},
},
Config: &recoder_grpc.InputConfig{},
Config: &encoder_grpc.InputConfig{},
})
if err != nil {
return 0, fmt.Errorf("query error: %w", err)
@@ -100,7 +100,7 @@ func (c *Client) CloseInput(
}
defer conn.Close()
_, err = client.CloseInput(ctx, &recoder_grpc.CloseInputRequest{
_, err = client.CloseInput(ctx, &encoder_grpc.CloseInputRequest{
InputID: uint64(inputID),
})
if err != nil {
@@ -111,7 +111,7 @@ func (c *Client) CloseInput(
}
type OutputID uint64
type OutputConfig = recoder.OutputConfig
type OutputConfig = encoder.OutputConfig
func (c *Client) NewOutputFromURL(
ctx context.Context,
@@ -125,16 +125,16 @@ func (c *Client) NewOutputFromURL(
}
defer conn.Close()
resp, err := client.NewOutput(ctx, &recoder_grpc.NewOutputRequest{
Path: &recoder_grpc.ResourcePath{
ResourcePath: &recoder_grpc.ResourcePath_Url{
Url: &recoder_grpc.ResourcePathURL{
resp, err := client.NewOutput(ctx, &encoder_grpc.NewOutputRequest{
Path: &encoder_grpc.ResourcePath{
ResourcePath: &encoder_grpc.ResourcePath_Url{
Url: &encoder_grpc.ResourcePathURL{
Url: url,
AuthKey: streamKey,
},
},
},
Config: &recoder_grpc.OutputConfig{},
Config: &encoder_grpc.OutputConfig{},
})
if err != nil {
return 0, fmt.Errorf("query error: %w", err)
@@ -153,7 +153,7 @@ func (c *Client) CloseOutput(
}
defer conn.Close()
_, err = client.CloseOutput(ctx, &recoder_grpc.CloseOutputRequest{
_, err = client.CloseOutput(ctx, &encoder_grpc.CloseOutputRequest{
OutputID: uint64(outputID),
})
if err != nil {
@@ -163,32 +163,32 @@ func (c *Client) CloseOutput(
return nil
}
type RecoderID uint64
type RecoderConfig = recoder.Config
type EncoderID uint64
type EncoderConfig = encoder.Config
func (c *Client) NewRecoder(
func (c *Client) NewEncoder(
ctx context.Context,
config RecoderConfig,
) (RecoderID, error) {
config EncoderConfig,
) (EncoderID, error) {
client, conn, err := c.grpcClient()
if err != nil {
return 0, err
}
defer conn.Close()
resp, err := client.NewRecoder(ctx, &recoder_grpc.NewRecoderRequest{
Config: &recoder_grpc.RecoderConfig{},
resp, err := client.NewEncoder(ctx, &encoder_grpc.NewEncoderRequest{
Config: &encoder_grpc.EncoderConfig{},
})
if err != nil {
return 0, fmt.Errorf("query error: %w", err)
}
return RecoderID(resp.GetId()), nil
return EncoderID(resp.GetId()), nil
}
func (c *Client) StartRecoding(
func (c *Client) StartEncoding(
ctx context.Context,
recoderID RecoderID,
recoderID EncoderID,
inputID InputID,
outputID OutputID,
) error {
@@ -198,8 +198,8 @@ func (c *Client) StartRecoding(
}
defer conn.Close()
_, err = client.StartRecoding(ctx, &recoder_grpc.StartRecodingRequest{
RecoderID: uint64(recoderID),
_, err = client.StartEncoding(ctx, &encoder_grpc.StartEncodingRequest{
EncoderID: uint64(recoderID),
InputID: uint64(inputID),
OutputID: uint64(outputID),
})
@@ -210,42 +210,42 @@ func (c *Client) StartRecoding(
return nil
}
type RecoderStats = recoder.Stats
type EncoderStats = encoder.Stats
func (c *Client) GetRecoderStats(
func (c *Client) GetEncoderStats(
ctx context.Context,
recoderID RecoderID,
) (*RecoderStats, error) {
recoderID EncoderID,
) (*EncoderStats, error) {
client, conn, err := c.grpcClient()
if err != nil {
return nil, err
}
defer conn.Close()
resp, err := client.GetRecoderStats(ctx, &recoder_grpc.GetRecoderStatsRequest{
RecoderID: uint64(recoderID),
resp, err := client.GetEncoderStats(ctx, &encoder_grpc.GetEncoderStatsRequest{
EncoderID: uint64(recoderID),
})
if err != nil {
return nil, fmt.Errorf("query error: %w", err)
}
return &RecoderStats{
return &EncoderStats{
BytesCountRead: resp.GetBytesCountRead(),
BytesCountWrote: resp.GetBytesCountWrote(),
}, nil
}
func (c *Client) RecodingEndedChan(
func (c *Client) EncodingEndedChan(
ctx context.Context,
recoderID RecoderID,
recoderID EncoderID,
) (<-chan struct{}, error) {
client, conn, err := c.grpcClient()
if err != nil {
return nil, err
}
waiter, err := client.RecodingEndedChan(ctx, &recoder_grpc.RecodingEndedChanRequest{
RecoderID: uint64(recoderID),
waiter, err := client.EncodingEndedChan(ctx, &encoder_grpc.EncodingEndedChanRequest{
EncoderID: uint64(recoderID),
})
if err != nil {
return nil, fmt.Errorf("query error: %w", err)

View File

@@ -0,0 +1,27 @@
package client
import (
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/grpc/go/encoder_grpc"
)
func logLevelGo2Protobuf(logLevel logger.Level) encoder_grpc.LoggingLevel {
switch logLevel {
case logger.LevelFatal:
return encoder_grpc.LoggingLevel_LoggingLevelFatal
case logger.LevelPanic:
return encoder_grpc.LoggingLevel_LoggingLevelPanic
case logger.LevelError:
return encoder_grpc.LoggingLevel_LoggingLevelError
case logger.LevelWarning:
return encoder_grpc.LoggingLevel_LoggingLevelWarn
case logger.LevelInfo:
return encoder_grpc.LoggingLevel_LoggingLevelInfo
case logger.LevelDebug:
return encoder_grpc.LoggingLevel_LoggingLevelDebug
case logger.LevelTrace:
return encoder_grpc.LoggingLevel_LoggingLevelTrace
default:
return encoder_grpc.LoggingLevel_LoggingLevelWarn
}
}

View File

@@ -11,22 +11,22 @@ import (
"os"
"github.com/facebookincubator/go-belt"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/process/server"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/process/server"
)
const (
EnvKeyIsRecoder = "IS_STREAMPANEL_RECODER"
EnvKeyIsEncoder = "IS_STREAMPANEL_RECODER"
)
func init() {
if os.Getenv(EnvKeyIsRecoder) != "" {
runRecoder()
if os.Getenv(EnvKeyIsEncoder) != "" {
runEncoder()
belt.Flush(context.TODO())
os.Exit(0)
}
}
func runRecoder() {
func runEncoder() {
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
panic(fmt.Errorf("failed to listen: %w", err))

View File

@@ -14,31 +14,31 @@ import (
child_process_manager "github.com/AgustinSRG/go-child-process-manager"
"github.com/facebookincubator/go-belt/tool/experimental/errmon"
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/process/client"
"github.com/xaionaro-go/streamctl/pkg/observability"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/process/client"
"github.com/xaionaro-go/streamctl/pkg/xpath"
)
type InputID = client.InputID
type InputConfig = recoder.InputConfig
type InputConfig = encoder.InputConfig
type OutputID = client.OutputID
type OutputConfig = recoder.OutputConfig
type OutputConfig = encoder.OutputConfig
type RecoderID = client.RecoderID
type RecoderConfig = recoder.Config
type EncoderID = client.EncoderID
type EncoderConfig = encoder.Config
type RecoderStats = recoder.Stats
type EncoderStats = encoder.Stats
type Recoder struct {
type Encoder struct {
*client.Client
Cmd *exec.Cmd
}
func Run(
ctx context.Context,
) (*Recoder, error) {
) (*Encoder, error) {
execPath, err := xpath.GetExecPath(os.Args[0])
if err != nil {
return nil, fmt.Errorf("unable to get self-path: %w", err)
@@ -49,7 +49,7 @@ func Run(
if err != nil {
return nil, fmt.Errorf("unable to initialize an stdout pipe: %w", err)
}
cmd.Env = append(os.Environ(), EnvKeyIsRecoder+"=1")
cmd.Env = append(os.Environ(), EnvKeyIsEncoder+"=1")
err = child_process_manager.ConfigureCommand(cmd)
errmon.ObserveErrorCtx(ctx, err)
err = cmd.Start()
@@ -80,17 +80,17 @@ func Run(
return nil, fmt.Errorf("unable to set the logging level to %s: %w", level, err)
}
return &Recoder{
return &Encoder{
Client: c,
Cmd: cmd,
}, nil
}
func (r *Recoder) Kill() error {
func (r *Encoder) Kill() error {
return r.Cmd.Process.Kill()
}
func (r *Recoder) Wait(ctx context.Context) error {
func (r *Encoder) Wait(ctx context.Context) error {
_, err := r.Cmd.Process.Wait()
return err
}

View File

@@ -7,33 +7,33 @@ import (
"context"
"fmt"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder"
)
type Recoder struct {
type Encoder struct {
*Client
}
func (r *Recoder) Kill() error {
func (r *Encoder) Kill() error {
return fmt.Errorf("not compiled with libav support")
}
func Run(
ctx context.Context,
) (*Recoder, error) {
) (*Encoder, error) {
return nil, fmt.Errorf("not compiled with libav support")
}
type Client struct{}
type InputID uint64
type InputConfig = recoder.InputConfig
type InputConfig = encoder.InputConfig
type OutputID uint64
type OutputConfig = recoder.OutputConfig
type OutputConfig = encoder.OutputConfig
type RecoderID uint64
type RecoderConfig = recoder.Config
type EncoderID uint64
type EncoderConfig = encoder.Config
func (c *Client) NewInputFromURL(
ctx context.Context,
@@ -53,34 +53,34 @@ func (c *Client) NewOutputFromURL(
return 0, fmt.Errorf("not compiled with libav support")
}
func (c *Client) StartRecoding(
func (c *Client) StartEncoding(
ctx context.Context,
recoderID RecoderID,
encoderID EncoderID,
inputID InputID,
outputID OutputID,
) error {
return fmt.Errorf("not compiled with libav support")
}
func (c *Client) NewRecoder(
func (c *Client) NewEncoder(
ctx context.Context,
config RecoderConfig,
) (RecoderID, error) {
config EncoderConfig,
) (EncoderID, error) {
return 0, fmt.Errorf("not compiled with libav support")
}
type RecoderStats = recoder.Stats
type EncoderStats = encoder.Stats
func (c *Client) GetRecoderStats(
func (c *Client) GetEncoderStats(
ctx context.Context,
recoderID RecoderID,
) (*RecoderStats, error) {
encoderID EncoderID,
) (*EncoderStats, error) {
return nil, fmt.Errorf("not compiled with libav support")
}
func (c *Client) RecodingEndedChan(
func (c *Client) EncodingEndedChan(
ctx context.Context,
recoderID RecoderID,
recoderID EncoderID,
) (<-chan struct{}, error) {
return nil, fmt.Errorf("not compiled with libav support")
}

View File

@@ -0,0 +1,29 @@
package server
import (
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/grpc/go/encoder_grpc"
)
func logLevelProtobuf2Go(logLevel encoder_grpc.LoggingLevel) logger.Level {
switch logLevel {
case encoder_grpc.LoggingLevel_LoggingLevelNone:
return logger.LevelFatal
case encoder_grpc.LoggingLevel_LoggingLevelFatal:
return logger.LevelFatal
case encoder_grpc.LoggingLevel_LoggingLevelPanic:
return logger.LevelPanic
case encoder_grpc.LoggingLevel_LoggingLevelError:
return logger.LevelError
case encoder_grpc.LoggingLevel_LoggingLevelWarn:
return logger.LevelWarning
case encoder_grpc.LoggingLevel_LoggingLevelInfo:
return logger.LevelInfo
case encoder_grpc.LoggingLevel_LoggingLevelDebug:
return logger.LevelDebug
case encoder_grpc.LoggingLevel_LoggingLevelTrace:
return logger.LevelTrace
default:
return logger.LevelUndefined
}
}

View File

@@ -8,19 +8,19 @@ import (
"github.com/facebookincubator/go-belt"
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/recoder"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/grpc/go/recoder_grpc"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/encoder"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/safeencoder/grpc/go/encoder_grpc"
"github.com/xaionaro-go/streamctl/pkg/xcontext"
"github.com/xaionaro-go/streamctl/pkg/xsync"
"google.golang.org/grpc"
)
type RecoderID uint64
type EncoderID uint64
type InputID uint64
type OutputID uint64
type GRPCServer struct {
recoder_grpc.UnimplementedRecoderServer
encoder_grpc.UnimplementedEncoderServer
GRPCServer *grpc.Server
IsStarted bool
@@ -28,27 +28,27 @@ type GRPCServer struct {
BeltLocker xsync.Mutex
Belt *belt.Belt
RecoderLocker xsync.Mutex
Recoder map[RecoderID]*recoder.Recoder
RecoderNextID atomic.Uint64
EncoderLocker xsync.Mutex
Encoder map[EncoderID]*encoder.Encoder
EncoderNextID atomic.Uint64
InputLocker xsync.Mutex
Input map[InputID]*recoder.Input
Input map[InputID]*encoder.Input
InputNextID atomic.Uint64
OutputLocker xsync.Mutex
Output map[OutputID]*recoder.Output
Output map[OutputID]*encoder.Output
OutputNextID atomic.Uint64
}
func NewServer() *GRPCServer {
srv := &GRPCServer{
GRPCServer: grpc.NewServer(),
Recoder: make(map[RecoderID]*recoder.Recoder),
Input: make(map[InputID]*recoder.Input),
Output: make(map[OutputID]*recoder.Output),
Encoder: make(map[EncoderID]*encoder.Encoder),
Input: make(map[InputID]*encoder.Input),
Output: make(map[OutputID]*encoder.Output),
}
recoder_grpc.RegisterRecoderServer(srv.GRPCServer, srv)
encoder_grpc.RegisterEncoderServer(srv.GRPCServer, srv)
return srv
}
@@ -77,24 +77,24 @@ func (srv *GRPCServer) ctx(ctx context.Context) context.Context {
func (srv *GRPCServer) SetLoggingLevel(
ctx context.Context,
req *recoder_grpc.SetLoggingLevelRequest,
) (*recoder_grpc.SetLoggingLevelReply, error) {
req *encoder_grpc.SetLoggingLevelRequest,
) (*encoder_grpc.SetLoggingLevelReply, error) {
ctx = srv.ctx(ctx)
srv.BeltLocker.Do(ctx, func() {
logLevel := logLevelProtobuf2Go(req.GetLevel())
l := logger.FromBelt(srv.Belt).WithLevel(logLevel)
srv.Belt = srv.Belt.WithTool(logger.ToolID, l)
})
return &recoder_grpc.SetLoggingLevelReply{}, nil
return &encoder_grpc.SetLoggingLevelReply{}, nil
}
func (srv *GRPCServer) NewInput(
ctx context.Context,
req *recoder_grpc.NewInputRequest,
) (*recoder_grpc.NewInputReply, error) {
req *encoder_grpc.NewInputRequest,
) (*encoder_grpc.NewInputReply, error) {
ctx = srv.ctx(ctx)
switch path := req.Path.GetResourcePath().(type) {
case *recoder_grpc.ResourcePath_Url:
case *encoder_grpc.ResourcePath_Url:
return srv.newInputByURL(ctx, path, req.Config)
default:
return nil, fmt.Errorf("the support of path type '%T' is not implemented", path)
@@ -103,11 +103,11 @@ func (srv *GRPCServer) NewInput(
func (srv *GRPCServer) newInputByURL(
ctx context.Context,
path *recoder_grpc.ResourcePath_Url,
_ *recoder_grpc.InputConfig,
) (*recoder_grpc.NewInputReply, error) {
config := recoder.InputConfig{}
input, err := recoder.NewInputFromURL(ctx, path.Url.Url, path.Url.AuthKey, config)
path *encoder_grpc.ResourcePath_Url,
_ *encoder_grpc.InputConfig,
) (*encoder_grpc.NewInputReply, error) {
config := encoder.InputConfig{}
input, err := encoder.NewInputFromURL(ctx, path.Url.Url, path.Url.AuthKey, config)
if err != nil {
return nil, fmt.Errorf(
"unable to initialize an input using URL '%s' and config %#+v",
@@ -121,15 +121,15 @@ func (srv *GRPCServer) newInputByURL(
srv.Input[inputID] = input
return inputID
})
return &recoder_grpc.NewInputReply{
return &encoder_grpc.NewInputReply{
Id: uint64(inputID),
}, nil
}
func (srv *GRPCServer) CloseInput(
ctx context.Context,
req *recoder_grpc.CloseInputRequest,
) (*recoder_grpc.CloseInputReply, error) {
req *encoder_grpc.CloseInputRequest,
) (*encoder_grpc.CloseInputReply, error) {
inputID := InputID(req.GetInputID())
err := xsync.DoR1(ctx, &srv.InputLocker, func() error {
input := srv.Input[inputID]
@@ -143,16 +143,16 @@ func (srv *GRPCServer) CloseInput(
if err != nil {
return nil, err
}
return &recoder_grpc.CloseInputReply{}, nil
return &encoder_grpc.CloseInputReply{}, nil
}
func (srv *GRPCServer) NewOutput(
ctx context.Context,
req *recoder_grpc.NewOutputRequest,
) (*recoder_grpc.NewOutputReply, error) {
req *encoder_grpc.NewOutputRequest,
) (*encoder_grpc.NewOutputReply, error) {
ctx = srv.ctx(ctx)
switch path := req.Path.GetResourcePath().(type) {
case *recoder_grpc.ResourcePath_Url:
case *encoder_grpc.ResourcePath_Url:
return srv.newOutputByURL(ctx, path, req.Config)
default:
return nil, fmt.Errorf("the support of path type '%T' is not implemented", path)
@@ -161,11 +161,11 @@ func (srv *GRPCServer) NewOutput(
func (srv *GRPCServer) newOutputByURL(
ctx context.Context,
path *recoder_grpc.ResourcePath_Url,
_ *recoder_grpc.OutputConfig,
) (*recoder_grpc.NewOutputReply, error) {
config := recoder.OutputConfig{}
output, err := recoder.NewOutputFromURL(ctx, path.Url.Url, path.Url.AuthKey, config)
path *encoder_grpc.ResourcePath_Url,
_ *encoder_grpc.OutputConfig,
) (*encoder_grpc.NewOutputReply, error) {
config := encoder.OutputConfig{}
output, err := encoder.NewOutputFromURL(ctx, path.Url.Url, path.Url.AuthKey, config)
if err != nil {
return nil, fmt.Errorf(
"unable to initialize an output using URL '%s' and config %#+v: %w",
@@ -180,15 +180,15 @@ func (srv *GRPCServer) newOutputByURL(
srv.Output[outputID] = output
return outputID
})
return &recoder_grpc.NewOutputReply{
return &encoder_grpc.NewOutputReply{
Id: uint64(outputID),
}, nil
}
func (srv *GRPCServer) CloseOutput(
ctx context.Context,
req *recoder_grpc.CloseOutputRequest,
) (*recoder_grpc.CloseOutputReply, error) {
req *encoder_grpc.CloseOutputRequest,
) (*encoder_grpc.CloseOutputReply, error) {
outputID := OutputID(req.GetOutputID())
err := xsync.DoR1(ctx, &srv.InputLocker, func() error {
output := srv.Output[outputID]
@@ -202,58 +202,58 @@ func (srv *GRPCServer) CloseOutput(
if err != nil {
return nil, err
}
return &recoder_grpc.CloseOutputReply{}, nil
return &encoder_grpc.CloseOutputReply{}, nil
}
func (srv *GRPCServer) NewRecoder(
func (srv *GRPCServer) NewEncoder(
ctx context.Context,
req *recoder_grpc.NewRecoderRequest,
) (*recoder_grpc.NewRecoderReply, error) {
req *encoder_grpc.NewEncoderRequest,
) (*encoder_grpc.NewEncoderReply, error) {
ctx = srv.ctx(ctx)
config := recoder.RecoderConfig{}
recoderInstance := recoder.New(config)
recoderID := xsync.DoR1(ctx, &srv.RecoderLocker, func() RecoderID {
recoderID := RecoderID(srv.RecoderNextID.Add(1))
srv.Recoder[recoderID] = recoderInstance
config := encoder.EncoderConfig{}
recoderInstance := encoder.New(config)
recoderID := xsync.DoR1(ctx, &srv.EncoderLocker, func() EncoderID {
recoderID := EncoderID(srv.EncoderNextID.Add(1))
srv.Encoder[recoderID] = recoderInstance
return recoderID
})
return &recoder_grpc.NewRecoderReply{
return &encoder_grpc.NewEncoderReply{
Id: uint64(recoderID),
}, nil
}
func (srv *GRPCServer) GetRecoderStats(
func (srv *GRPCServer) GetEncoderStats(
ctx context.Context,
req *recoder_grpc.GetRecoderStatsRequest,
) (*recoder_grpc.GetRecoderStatsReply, error) {
recoderID := RecoderID(req.GetRecoderID())
recoder := xsync.DoR1(ctx, &srv.RecoderLocker, func() *recoder.Recoder {
return srv.Recoder[recoderID]
req *encoder_grpc.GetEncoderStatsRequest,
) (*encoder_grpc.GetEncoderStatsReply, error) {
recoderID := EncoderID(req.GetEncoderID())
recoder := xsync.DoR1(ctx, &srv.EncoderLocker, func() *encoder.Encoder {
return srv.Encoder[recoderID]
})
return &recoder_grpc.GetRecoderStatsReply{
BytesCountRead: recoder.RecoderStats.BytesCountRead.Load(),
BytesCountWrote: recoder.RecoderStats.BytesCountWrote.Load(),
return &encoder_grpc.GetEncoderStatsReply{
BytesCountRead: recoder.EncoderStats.BytesCountRead.Load(),
BytesCountWrote: recoder.EncoderStats.BytesCountWrote.Load(),
}, nil
}
func (srv *GRPCServer) StartRecoding(
ctx context.Context,
req *recoder_grpc.StartRecodingRequest,
) (*recoder_grpc.StartRecodingReply, error) {
req *encoder_grpc.StartEncodingRequest,
) (*encoder_grpc.StartEncodingReply, error) {
ctx = srv.ctx(ctx)
recoderID := RecoderID(req.GetRecoderID())
recoderID := EncoderID(req.GetEncoderID())
inputID := InputID(req.GetInputID())
outputID := OutputID(req.GetOutputID())
srv.RecoderLocker.ManualLock(ctx)
srv.EncoderLocker.ManualLock(ctx)
srv.InputLocker.ManualLock(ctx)
srv.OutputLocker.ManualLock(ctx)
defer srv.RecoderLocker.ManualUnlock(ctx)
defer srv.EncoderLocker.ManualUnlock(ctx)
defer srv.InputLocker.ManualUnlock(ctx)
defer srv.OutputLocker.ManualUnlock(ctx)
recoder := srv.Recoder[recoderID]
recoder := srv.Encoder[recoderID]
if recoder == nil {
return nil, fmt.Errorf("the recorder with ID '%v' does not exist", recoderID)
}
@@ -273,23 +273,23 @@ func (srv *GRPCServer) StartRecoding(
return nil, fmt.Errorf("unable to start recoding")
}
return &recoder_grpc.StartRecodingReply{}, nil
return &encoder_grpc.StartEncodingReply{}, nil
}
func (srv *GRPCServer) RecodingEndedChan(
req *recoder_grpc.RecodingEndedChanRequest,
streamSrv recoder_grpc.Recoder_RecodingEndedChanServer,
req *encoder_grpc.EncodingEndedChanRequest,
streamSrv encoder_grpc.Encoder_EncodingEndedChanServer,
) (_ret error) {
ctx := srv.ctx(streamSrv.Context())
recoderID := RecoderID(req.GetRecoderID())
recoderID := EncoderID(req.GetEncoderID())
logger.Tracef(ctx, "RecodingEndedChan(%v)", recoderID)
defer func() {
logger.Tracef(ctx, "/RecodingEndedChan(%v): %v", recoderID, _ret)
}()
recoder := xsync.DoR1(ctx, &srv.RecoderLocker, func() *recoder.Recoder {
return srv.Recoder[recoderID]
recoder := xsync.DoR1(ctx, &srv.EncoderLocker, func() *encoder.Encoder {
return srv.Encoder[recoderID]
})
select {
@@ -298,5 +298,5 @@ func (srv *GRPCServer) RecodingEndedChan(
case <-recoder.WaiterChan:
}
return streamSrv.Send(&recoder_grpc.RecodingEndedChanReply{})
return streamSrv.Send(&encoder_grpc.EncodingEndedChanReply{})
}

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
import (
"io"

View File

@@ -1,3 +1,3 @@
package recoder
package encoder
type OutputConfig struct{}

View File

@@ -1,4 +1,4 @@
package recoder
package encoder
type Stats struct {
BytesCountRead uint64

View File

@@ -10,7 +10,7 @@ import (
"github.com/hashicorp/go-multierror"
"github.com/xaionaro-go/go-rtmp"
rtmpmsg "github.com/xaionaro-go/go-rtmp/message"
"github.com/xaionaro-go/streamctl/pkg/recoder"
recoder "github.com/xaionaro-go/streamctl/pkg/encoder"
yutoppgortmp "github.com/xaionaro-go/streamctl/pkg/streamserver/implementations/xaionaro-go-rtmp"
"github.com/xaionaro-go/streamctl/pkg/xsync"
flvtag "github.com/yutopp/go-flv/tag"
@@ -20,7 +20,7 @@ const (
chunkSize = 128
)
type Recoder struct {
type Encoder struct {
Locker xsync.Mutex
Stream *rtmp.Stream
CancelFunc context.CancelFunc
@@ -30,19 +30,19 @@ type Recoder struct {
eventChan chan *flvtag.FlvTag
}
var _ recoder.Recoder = (*Recoder)(nil)
var _ recoder.NewInputFromPublisherer = (*Recoder)(nil)
var _ recoder.Encoder = (*Encoder)(nil)
var _ recoder.NewInputFromPublisherer = (*Encoder)(nil)
func (RecoderFactory) New(
func (EncoderFactory) New(
ctx context.Context,
cfg recoder.Config,
) (recoder.Recoder, error) {
return &Recoder{
) (recoder.Encoder, error) {
return &Encoder{
eventChan: make(chan *flvtag.FlvTag),
}, nil
}
func (r *Recoder) StartRecoding(
func (r *Encoder) StartRecoding(
ctx context.Context,
inputIface recoder.Input,
outputIface recoder.Output,
@@ -110,7 +110,7 @@ func (r *Recoder) StartRecoding(
return nil
}
func (r *Recoder) WaitForRecordingEnd(
func (r *Encoder) WaitForRecordingEnd(
ctx context.Context,
) error {
var closeChan <-chan struct{}
@@ -134,17 +134,17 @@ func (r *Recoder) WaitForRecordingEnd(
return nil
}
func (r *Recoder) GetStats(context.Context) (*recoder.Stats, error) {
func (r *Encoder) GetStats(context.Context) (*recoder.Stats, error) {
return &recoder.Stats{
BytesCountRead: r.ReadCount.Load(),
BytesCountWrote: r.WriteCount.Load(),
}, nil
}
func (r *Recoder) Close() (_err error) {
func (r *Encoder) Close() (_err error) {
ctx := context.TODO()
logger.Debug(ctx, "closing the Recoder")
defer func() { logger.Debugf(ctx, "closed the Recoder: %v", _err) }()
logger.Debug(ctx, "closing the Encoder")
defer func() { logger.Debugf(ctx, "closed the Encoder: %v", _err) }()
return xsync.DoR1(ctx, &r.Locker, func() error {
var result *multierror.Error

View File

@@ -0,0 +1,11 @@
package xaionarogortmp
import "github.com/xaionaro-go/streamctl/pkg/encoder"
type EncoderFactory struct{}
var _ encoder.Factory = (*EncoderFactory)(nil)
func NewEncoderFactory() *EncoderFactory {
return &EncoderFactory{}
}

View File

@@ -9,7 +9,7 @@ import (
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/go-rtmp"
rtmpmsg "github.com/xaionaro-go/go-rtmp/message"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder"
xaionarogortmp "github.com/xaionaro-go/streamctl/pkg/streamserver/implementations/xaionaro-go-rtmp"
"github.com/xaionaro-go/streamctl/pkg/streamserver/types"
"github.com/xaionaro-go/streamctl/pkg/xsync"
@@ -21,7 +21,7 @@ type Input struct {
Pubsub *xaionarogortmp.Pubsub
}
var _ recoder.Input = (*Input)(nil)
var _ encoder.Input = (*Input)(nil)
func streamID2LocalAppName(
streamID types.StreamID,
@@ -34,11 +34,11 @@ func streamID2LocalAppName(
return types.AppKey(localAppName)
}
func (r *Recoder) NewInputFromPublisher(
func (r *Encoder) NewInputFromPublisher(
ctx context.Context,
publisherIface types.Publisher,
cfg recoder.InputConfig,
) (recoder.Input, error) {
cfg encoder.InputConfig,
) (encoder.Input, error) {
publisher, ok := publisherIface.(*xaionarogortmp.Pubsub)
if !ok {
return nil, fmt.Errorf(
@@ -53,12 +53,12 @@ func (r *Recoder) NewInputFromPublisher(
}, nil
}
func (r *Recoder) NewInputFromURL(
func (r *Encoder) NewInputFromURL(
ctx context.Context,
urlString string,
authKey string,
cfg recoder.InputConfig,
) (_ recoder.Input, _err error) {
cfg encoder.InputConfig,
) (_ encoder.Input, _err error) {
inClient, err := newRTMPClient(ctx, urlString)
if err != nil {
return nil, fmt.Errorf("unable to connect to the input endpoint '%s': %w", urlString, err)

View File

@@ -11,7 +11,7 @@ import (
"github.com/hashicorp/go-multierror"
"github.com/xaionaro-go/go-rtmp"
rtmpmsg "github.com/xaionaro-go/go-rtmp/message"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/xsync"
)
@@ -21,14 +21,14 @@ type Output struct {
StreamKey string
}
var _ recoder.Output = (*Output)(nil)
var _ encoder.Output = (*Output)(nil)
func (r *Recoder) NewOutputFromURL(
func (r *Encoder) NewOutputFromURL(
ctx context.Context,
urlString string,
streamKey string,
cfg recoder.OutputConfig,
) (_ recoder.Output, _err error) {
cfg encoder.OutputConfig,
) (_ encoder.Output, _err error) {
var output *Output
defer func() {
if r := recover(); r != nil {

View File

@@ -11,5 +11,5 @@ func NewStreamForwards(
s StreamServer,
platformsController types.PlatformsController,
) *StreamForwards {
return streamforward.NewStreamForwards(s, NewRecoderFactory(), platformsController)
return streamforward.NewStreamForwards(s, NewEncoderFactory(), platformsController)
}

View File

@@ -11,7 +11,7 @@ import (
flvtag "github.com/yutopp/go-flv/tag"
)
func (r *Recoder) subCallback(
func (r *Encoder) subCallback(
stream *rtmp.Stream,
) func(
ctx context.Context,

View File

@@ -3,7 +3,7 @@ package builtin
import (
"context"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/encoder"
)
type frameReader struct {
@@ -18,6 +18,6 @@ func (p *Player) newFrameReader(ctx context.Context) *frameReader {
}
}
func (fr *frameReader) ReadFrame(frame *recoder.Frame) error {
func (fr *frameReader) ReadFrame(frame *encoder.Frame) error {
return fr.Player.processFrame(fr.Context, frame)
}

View File

@@ -4,12 +4,12 @@ import (
"context"
"fmt"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/recoder"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/encoder"
)
func (p *Player) initImageFor(
_ context.Context,
frame *recoder.Frame,
frame *encoder.Frame,
) error {
var err error
p.currentImage, err = frame.Data().GuessImageFormat()

View File

@@ -12,8 +12,8 @@ import (
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/audio"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav/encoder"
"github.com/xaionaro-go/streamctl/pkg/observability"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/recoder"
"github.com/xaionaro-go/streamctl/pkg/xsync"
)
@@ -71,15 +71,15 @@ func (p *Player) openURL(
ctx context.Context,
link string,
) error {
decoderCfg := recoder.DecoderConfig{}
decoder, err := recoder.NewDecoder(decoderCfg)
decoderCfg := encoder.DecoderConfig{}
decoder, err := encoder.NewDecoder(decoderCfg)
logger.Tracef(ctx, "NewDecoder(%#+v): %v", decoderCfg, err)
if err != nil {
return fmt.Errorf("unable to initialize a decoder: %w", err)
}
inputCfg := recoder.InputConfig{}
input, err := recoder.NewInputFromURL(ctx, link, "", inputCfg)
inputCfg := encoder.InputConfig{}
input, err := encoder.NewInputFromURL(ctx, link, "", inputCfg)
logger.Tracef(ctx, "NewInputFromURL(ctx, '%s', '', %#+v): %v", link, inputCfg, err)
if err != nil {
return fmt.Errorf("unable to open '%s': %w", link, err)
@@ -123,7 +123,7 @@ func (p *Player) openURL(
func (p *Player) processFrame(
ctx context.Context,
frame *recoder.Frame,
frame *encoder.Frame,
) error {
logger.Tracef(ctx, "processFrame: pos: %v; dur: %v; pts: %v; time_base: %v", frame.Position(), frame.MaxPosition(), frame.Pts(), frame.DecoderContext.TimeBase())
defer func() {
@@ -153,7 +153,7 @@ func (p *Player) onSeek(
func (p *Player) processVideoFrame(
ctx context.Context,
frame *recoder.Frame,
frame *encoder.Frame,
) error {
logger.Tracef(ctx, "processVideoFrame")
defer logger.Tracef(ctx, "/processVideoFrame")
@@ -198,7 +198,7 @@ func (p *Player) renderCurrentPicture() error {
func (p *Player) processAudioFrame(
ctx context.Context,
frame *recoder.Frame,
frame *encoder.Frame,
) error {
logger.Tracef(ctx, "processAudioFrame")
defer logger.Tracef(ctx, "/processAudioFrame")

View File

@@ -1,19 +0,0 @@
package livego
import (
"context"
"github.com/xaionaro-go/streamctl/pkg/recoder"
)
type RecoderFactory struct{}
var _ recoder.Factory = (*RecoderFactory)(nil)
func NewRecoderFactory() *RecoderFactory {
return &RecoderFactory{}
}
func (RecoderFactory) New(ctx context.Context, cfg recoder.Config) (recoder.Recoder, error) {
return &Recoder{}, nil
}

View File

@@ -1,34 +0,0 @@
package libav
import (
"context"
"fmt"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder"
)
type RecoderFactory struct{}
var _ recoder.Factory = (*RecoderFactory)(nil)
func NewRecoderFactory() *RecoderFactory {
return &RecoderFactory{}
}
func (RecoderFactory) New(ctx context.Context, cfg recoder.Config) (recoder.Recoder, error) {
process, err := saferecoder.NewProcess(ctx)
if err != nil {
return nil, fmt.Errorf("unable to initialize the process: %w", err)
}
recoderInstance, err := process.NewRecoder(cfg)
if err != nil {
return nil, fmt.Errorf("unable to initialize the recoder: %w", err)
}
return &Recoder{
Process: process,
Recoder: recoderInstance,
}, nil
}

View File

@@ -1,5 +0,0 @@
all: go
go:
protoc --go_out=. --go-grpc_out=. recoder.proto

View File

@@ -1,421 +0,0 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc v3.21.12
// source: recoder.proto
package recoder_grpc
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// RecoderClient is the client API for Recoder service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type RecoderClient interface {
SetLoggingLevel(ctx context.Context, in *SetLoggingLevelRequest, opts ...grpc.CallOption) (*SetLoggingLevelReply, error)
NewInput(ctx context.Context, in *NewInputRequest, opts ...grpc.CallOption) (*NewInputReply, error)
NewOutput(ctx context.Context, in *NewOutputRequest, opts ...grpc.CallOption) (*NewOutputReply, error)
NewRecoder(ctx context.Context, in *NewRecoderRequest, opts ...grpc.CallOption) (*NewRecoderReply, error)
CloseInput(ctx context.Context, in *CloseInputRequest, opts ...grpc.CallOption) (*CloseInputReply, error)
CloseOutput(ctx context.Context, in *CloseOutputRequest, opts ...grpc.CallOption) (*CloseOutputReply, error)
GetRecoderStats(ctx context.Context, in *GetRecoderStatsRequest, opts ...grpc.CallOption) (*GetRecoderStatsReply, error)
StartRecoding(ctx context.Context, in *StartRecodingRequest, opts ...grpc.CallOption) (*StartRecodingReply, error)
RecodingEndedChan(ctx context.Context, in *RecodingEndedChanRequest, opts ...grpc.CallOption) (Recoder_RecodingEndedChanClient, error)
}
type recoderClient struct {
cc grpc.ClientConnInterface
}
func NewRecoderClient(cc grpc.ClientConnInterface) RecoderClient {
return &recoderClient{cc}
}
func (c *recoderClient) SetLoggingLevel(ctx context.Context, in *SetLoggingLevelRequest, opts ...grpc.CallOption) (*SetLoggingLevelReply, error) {
out := new(SetLoggingLevelReply)
err := c.cc.Invoke(ctx, "/recoder_grpc.Recoder/SetLoggingLevel", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *recoderClient) NewInput(ctx context.Context, in *NewInputRequest, opts ...grpc.CallOption) (*NewInputReply, error) {
out := new(NewInputReply)
err := c.cc.Invoke(ctx, "/recoder_grpc.Recoder/NewInput", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *recoderClient) NewOutput(ctx context.Context, in *NewOutputRequest, opts ...grpc.CallOption) (*NewOutputReply, error) {
out := new(NewOutputReply)
err := c.cc.Invoke(ctx, "/recoder_grpc.Recoder/NewOutput", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *recoderClient) NewRecoder(ctx context.Context, in *NewRecoderRequest, opts ...grpc.CallOption) (*NewRecoderReply, error) {
out := new(NewRecoderReply)
err := c.cc.Invoke(ctx, "/recoder_grpc.Recoder/NewRecoder", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *recoderClient) CloseInput(ctx context.Context, in *CloseInputRequest, opts ...grpc.CallOption) (*CloseInputReply, error) {
out := new(CloseInputReply)
err := c.cc.Invoke(ctx, "/recoder_grpc.Recoder/CloseInput", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *recoderClient) CloseOutput(ctx context.Context, in *CloseOutputRequest, opts ...grpc.CallOption) (*CloseOutputReply, error) {
out := new(CloseOutputReply)
err := c.cc.Invoke(ctx, "/recoder_grpc.Recoder/CloseOutput", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *recoderClient) GetRecoderStats(ctx context.Context, in *GetRecoderStatsRequest, opts ...grpc.CallOption) (*GetRecoderStatsReply, error) {
out := new(GetRecoderStatsReply)
err := c.cc.Invoke(ctx, "/recoder_grpc.Recoder/GetRecoderStats", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *recoderClient) StartRecoding(ctx context.Context, in *StartRecodingRequest, opts ...grpc.CallOption) (*StartRecodingReply, error) {
out := new(StartRecodingReply)
err := c.cc.Invoke(ctx, "/recoder_grpc.Recoder/StartRecoding", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *recoderClient) RecodingEndedChan(ctx context.Context, in *RecodingEndedChanRequest, opts ...grpc.CallOption) (Recoder_RecodingEndedChanClient, error) {
stream, err := c.cc.NewStream(ctx, &Recoder_ServiceDesc.Streams[0], "/recoder_grpc.Recoder/RecodingEndedChan", opts...)
if err != nil {
return nil, err
}
x := &recoderRecodingEndedChanClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type Recoder_RecodingEndedChanClient interface {
Recv() (*RecodingEndedChanReply, error)
grpc.ClientStream
}
type recoderRecodingEndedChanClient struct {
grpc.ClientStream
}
func (x *recoderRecodingEndedChanClient) Recv() (*RecodingEndedChanReply, error) {
m := new(RecodingEndedChanReply)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// RecoderServer is the server API for Recoder service.
// All implementations must embed UnimplementedRecoderServer
// for forward compatibility
type RecoderServer interface {
SetLoggingLevel(context.Context, *SetLoggingLevelRequest) (*SetLoggingLevelReply, error)
NewInput(context.Context, *NewInputRequest) (*NewInputReply, error)
NewOutput(context.Context, *NewOutputRequest) (*NewOutputReply, error)
NewRecoder(context.Context, *NewRecoderRequest) (*NewRecoderReply, error)
CloseInput(context.Context, *CloseInputRequest) (*CloseInputReply, error)
CloseOutput(context.Context, *CloseOutputRequest) (*CloseOutputReply, error)
GetRecoderStats(context.Context, *GetRecoderStatsRequest) (*GetRecoderStatsReply, error)
StartRecoding(context.Context, *StartRecodingRequest) (*StartRecodingReply, error)
RecodingEndedChan(*RecodingEndedChanRequest, Recoder_RecodingEndedChanServer) error
mustEmbedUnimplementedRecoderServer()
}
// UnimplementedRecoderServer must be embedded to have forward compatible implementations.
type UnimplementedRecoderServer struct {
}
func (UnimplementedRecoderServer) SetLoggingLevel(context.Context, *SetLoggingLevelRequest) (*SetLoggingLevelReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SetLoggingLevel not implemented")
}
func (UnimplementedRecoderServer) NewInput(context.Context, *NewInputRequest) (*NewInputReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method NewInput not implemented")
}
func (UnimplementedRecoderServer) NewOutput(context.Context, *NewOutputRequest) (*NewOutputReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method NewOutput not implemented")
}
func (UnimplementedRecoderServer) NewRecoder(context.Context, *NewRecoderRequest) (*NewRecoderReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method NewRecoder not implemented")
}
func (UnimplementedRecoderServer) CloseInput(context.Context, *CloseInputRequest) (*CloseInputReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method CloseInput not implemented")
}
func (UnimplementedRecoderServer) CloseOutput(context.Context, *CloseOutputRequest) (*CloseOutputReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method CloseOutput not implemented")
}
func (UnimplementedRecoderServer) GetRecoderStats(context.Context, *GetRecoderStatsRequest) (*GetRecoderStatsReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetRecoderStats not implemented")
}
func (UnimplementedRecoderServer) StartRecoding(context.Context, *StartRecodingRequest) (*StartRecodingReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method StartRecoding not implemented")
}
func (UnimplementedRecoderServer) RecodingEndedChan(*RecodingEndedChanRequest, Recoder_RecodingEndedChanServer) error {
return status.Errorf(codes.Unimplemented, "method RecodingEndedChan not implemented")
}
func (UnimplementedRecoderServer) mustEmbedUnimplementedRecoderServer() {}
// UnsafeRecoderServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to RecoderServer will
// result in compilation errors.
type UnsafeRecoderServer interface {
mustEmbedUnimplementedRecoderServer()
}
func RegisterRecoderServer(s grpc.ServiceRegistrar, srv RecoderServer) {
s.RegisterService(&Recoder_ServiceDesc, srv)
}
func _Recoder_SetLoggingLevel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(SetLoggingLevelRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RecoderServer).SetLoggingLevel(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/recoder_grpc.Recoder/SetLoggingLevel",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RecoderServer).SetLoggingLevel(ctx, req.(*SetLoggingLevelRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Recoder_NewInput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NewInputRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RecoderServer).NewInput(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/recoder_grpc.Recoder/NewInput",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RecoderServer).NewInput(ctx, req.(*NewInputRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Recoder_NewOutput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NewOutputRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RecoderServer).NewOutput(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/recoder_grpc.Recoder/NewOutput",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RecoderServer).NewOutput(ctx, req.(*NewOutputRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Recoder_NewRecoder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(NewRecoderRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RecoderServer).NewRecoder(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/recoder_grpc.Recoder/NewRecoder",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RecoderServer).NewRecoder(ctx, req.(*NewRecoderRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Recoder_CloseInput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CloseInputRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RecoderServer).CloseInput(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/recoder_grpc.Recoder/CloseInput",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RecoderServer).CloseInput(ctx, req.(*CloseInputRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Recoder_CloseOutput_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CloseOutputRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RecoderServer).CloseOutput(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/recoder_grpc.Recoder/CloseOutput",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RecoderServer).CloseOutput(ctx, req.(*CloseOutputRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Recoder_GetRecoderStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetRecoderStatsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RecoderServer).GetRecoderStats(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/recoder_grpc.Recoder/GetRecoderStats",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RecoderServer).GetRecoderStats(ctx, req.(*GetRecoderStatsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Recoder_StartRecoding_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(StartRecodingRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(RecoderServer).StartRecoding(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/recoder_grpc.Recoder/StartRecoding",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RecoderServer).StartRecoding(ctx, req.(*StartRecodingRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Recoder_RecodingEndedChan_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(RecodingEndedChanRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(RecoderServer).RecodingEndedChan(m, &recoderRecodingEndedChanServer{stream})
}
type Recoder_RecodingEndedChanServer interface {
Send(*RecodingEndedChanReply) error
grpc.ServerStream
}
type recoderRecodingEndedChanServer struct {
grpc.ServerStream
}
func (x *recoderRecodingEndedChanServer) Send(m *RecodingEndedChanReply) error {
return x.ServerStream.SendMsg(m)
}
// Recoder_ServiceDesc is the grpc.ServiceDesc for Recoder service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Recoder_ServiceDesc = grpc.ServiceDesc{
ServiceName: "recoder_grpc.Recoder",
HandlerType: (*RecoderServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SetLoggingLevel",
Handler: _Recoder_SetLoggingLevel_Handler,
},
{
MethodName: "NewInput",
Handler: _Recoder_NewInput_Handler,
},
{
MethodName: "NewOutput",
Handler: _Recoder_NewOutput_Handler,
},
{
MethodName: "NewRecoder",
Handler: _Recoder_NewRecoder_Handler,
},
{
MethodName: "CloseInput",
Handler: _Recoder_CloseInput_Handler,
},
{
MethodName: "CloseOutput",
Handler: _Recoder_CloseOutput_Handler,
},
{
MethodName: "GetRecoderStats",
Handler: _Recoder_GetRecoderStats_Handler,
},
{
MethodName: "StartRecoding",
Handler: _Recoder_StartRecoding_Handler,
},
},
Streams: []grpc.StreamDesc{
{
StreamName: "RecodingEndedChan",
Handler: _Recoder_RecodingEndedChan_Handler,
ServerStreams: true,
},
},
Metadata: "recoder.proto",
}

View File

@@ -1,27 +0,0 @@
package client
import (
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/grpc/go/recoder_grpc"
)
func logLevelGo2Protobuf(logLevel logger.Level) recoder_grpc.LoggingLevel {
switch logLevel {
case logger.LevelFatal:
return recoder_grpc.LoggingLevel_LoggingLevelFatal
case logger.LevelPanic:
return recoder_grpc.LoggingLevel_LoggingLevelPanic
case logger.LevelError:
return recoder_grpc.LoggingLevel_LoggingLevelError
case logger.LevelWarning:
return recoder_grpc.LoggingLevel_LoggingLevelWarn
case logger.LevelInfo:
return recoder_grpc.LoggingLevel_LoggingLevelInfo
case logger.LevelDebug:
return recoder_grpc.LoggingLevel_LoggingLevelDebug
case logger.LevelTrace:
return recoder_grpc.LoggingLevel_LoggingLevelTrace
default:
return recoder_grpc.LoggingLevel_LoggingLevelWarn
}
}

View File

@@ -1,29 +0,0 @@
package server
import (
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/grpc/go/recoder_grpc"
)
func logLevelProtobuf2Go(logLevel recoder_grpc.LoggingLevel) logger.Level {
switch logLevel {
case recoder_grpc.LoggingLevel_LoggingLevelNone:
return logger.LevelFatal
case recoder_grpc.LoggingLevel_LoggingLevelFatal:
return logger.LevelFatal
case recoder_grpc.LoggingLevel_LoggingLevelPanic:
return logger.LevelPanic
case recoder_grpc.LoggingLevel_LoggingLevelError:
return logger.LevelError
case recoder_grpc.LoggingLevel_LoggingLevelWarn:
return logger.LevelWarning
case recoder_grpc.LoggingLevel_LoggingLevelInfo:
return logger.LevelInfo
case recoder_grpc.LoggingLevel_LoggingLevelDebug:
return logger.LevelDebug
case recoder_grpc.LoggingLevel_LoggingLevelTrace:
return logger.LevelTrace
default:
return logger.LevelUndefined
}
}

View File

@@ -1,78 +0,0 @@
package saferecoder
import (
"context"
"fmt"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/recoder/types"
"github.com/xaionaro-go/streamctl/pkg/recoder/libav/saferecoder/process"
)
type Packet = types.Packet
type RecoderID = process.RecoderID
type RecoderConfig = process.RecoderConfig
type Recoder struct {
Process *Process
ID RecoderID
}
func (p *Process) NewRecoder(
cfg RecoderConfig,
) (*Recoder, error) {
recoderID, err := p.processBackend.Client.NewRecoder(context.TODO(), cfg)
if err != nil {
return nil, err
}
return &Recoder{
Process: p,
ID: RecoderID(recoderID),
}, nil
}
func (r *Recoder) Recode(
ctx context.Context,
input *Input,
output *Output,
) error {
err := r.StartRecoding(ctx, input, output)
if err != nil {
return fmt.Errorf("got an error while starting the recording: %w", err)
}
if err != r.Wait(ctx) {
return fmt.Errorf("got an error while waiting for a completion: %w", err)
}
return nil
}
func (r *Recoder) StartRecoding(
ctx context.Context,
input *Input,
output *Output,
) error {
return r.Process.processBackend.Client.StartRecoding(
context.TODO(),
r.ID,
input.ID,
output.ID,
)
}
type RecoderStats = recoder.Stats
func (r *Recoder) GetStats(ctx context.Context) (*RecoderStats, error) {
return r.Process.processBackend.Client.GetRecoderStats(ctx, r.ID)
}
func (r *Recoder) Wait(ctx context.Context) error {
ch, err := r.Process.Client.RecodingEndedChan(ctx, r.ID)
if err != nil {
return err
}
<-ch
return nil
}

View File

@@ -1,11 +0,0 @@
package xaionarogortmp
import "github.com/xaionaro-go/streamctl/pkg/recoder"
type RecoderFactory struct{}
var _ recoder.Factory = (*RecoderFactory)(nil)
func NewRecoderFactory() *RecoderFactory {
return &RecoderFactory{}
}

View File

@@ -1,7 +1,7 @@
package streamforward
import (
"github.com/xaionaro-go/streamctl/pkg/recoder/libav"
"github.com/xaionaro-go/streamctl/pkg/encoder/libav"
"github.com/xaionaro-go/streamctl/pkg/streamserver/streamforward"
"github.com/xaionaro-go/streamctl/pkg/streamserver/types"
)
@@ -12,5 +12,5 @@ func NewStreamForwards(
s StreamServer,
platformsController types.PlatformsController,
) *StreamForwards {
return streamforward.NewStreamForwards(s, libav.NewRecoderFactory(), platformsController)
return streamforward.NewStreamForwards(s, libav.NewEncoderFactory(), platformsController)
}

View File

@@ -1,7 +1,7 @@
package streamforward
import (
"github.com/xaionaro-go/streamctl/pkg/recoder/xaionaro-go-rtmp"
xaionarogortmp "github.com/xaionaro-go/streamctl/pkg/encoder/xaionaro-go-rtmp"
"github.com/xaionaro-go/streamctl/pkg/streamserver/streamforward"
"github.com/xaionaro-go/streamctl/pkg/streamserver/types"
)
@@ -14,7 +14,7 @@ func NewStreamForwards(
) *StreamForwards {
return streamforward.NewStreamForwards(
s,
xaionarogortmp.NewRecoderFactory(),
xaionarogortmp.NewEncoderFactory(),
platformsController,
)
}

View File

@@ -12,10 +12,10 @@ import (
"github.com/facebookincubator/go-belt"
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/go-rtmp"
xaionarogortmp "github.com/xaionaro-go/streamctl/pkg/encoder/xaionaro-go-rtmp"
"github.com/xaionaro-go/streamctl/pkg/observability"
"github.com/xaionaro-go/streamctl/pkg/player"
playertypes "github.com/xaionaro-go/streamctl/pkg/player/types"
xaionarogortmp "github.com/xaionaro-go/streamctl/pkg/recoder/xaionaro-go-rtmp"
"github.com/xaionaro-go/streamctl/pkg/streamplayer"
yutoppgortmp "github.com/xaionaro-go/streamctl/pkg/streamserver/implementations/xaionaro-go-rtmp"
"github.com/xaionaro-go/streamctl/pkg/streamserver/implementations/xaionaro-go-rtmp/streamforward"

View File

@@ -11,8 +11,8 @@ import (
"github.com/facebookincubator/go-belt/tool/experimental/errmon"
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/hashicorp/go-multierror"
recoder "github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/observability"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/streamserver/types"
"github.com/xaionaro-go/streamctl/pkg/xsync"
)
@@ -34,13 +34,13 @@ type ActiveStreamForwarding struct {
DestinationStreamKey string
ReadCount atomic.Uint64
WriteCount atomic.Uint64
RecoderFactory recoder.Factory
EncoderFactory recoder.Factory
PauseFunc func(ctx context.Context, fwd *ActiveStreamForwarding)
cancelFunc context.CancelFunc
locker xsync.Mutex
recoder recoder.Recoder
recoder recoder.Encoder
recodingCancelFunc context.CancelFunc
}
@@ -74,7 +74,7 @@ func (fwds *StreamForwards) NewActiveStreamForward(
return nil, fmt.Errorf("unable to parse URL '%s': %w", urlString, err)
}
fwd := &ActiveStreamForwarding{
RecoderFactory: fwds.RecoderFactory,
EncoderFactory: fwds.EncoderFactory,
StreamForwards: fwds,
StreamID: streamID,
DestinationURL: urlParsed,
@@ -215,7 +215,7 @@ func (fwd *ActiveStreamForwarding) waitForPublisherAndStart(
})
}()
recoderInstance, err := fwd.RecoderFactory.New(ctx, recoder.Config{})
recoderInstance, err := fwd.EncoderFactory.New(ctx, recoder.Config{})
if err != nil {
return fmt.Errorf("unable to initialize a recoder: %w", err)
}
@@ -324,7 +324,7 @@ func (fwd *ActiveStreamForwarding) waitForPublisherAndStart(
func (fwd *ActiveStreamForwarding) openInputFor(
ctx context.Context,
recoderInstance recoder.Recoder,
recoderInstance recoder.Encoder,
publisher types.Publisher,
) (recoder.Input, error) {
inputURL, err := fwd.getLocalhostEndpoint(ctx)
@@ -350,7 +350,7 @@ func (fwd *ActiveStreamForwarding) openInputFor(
func (fwd *ActiveStreamForwarding) openOutputFor(
ctx context.Context,
recoderInstance recoder.Recoder,
recoderInstance recoder.Encoder,
) (recoder.Output, error) {
output, err := recoderInstance.NewOutputFromURL(
ctx,

View File

@@ -10,8 +10,8 @@ import (
"github.com/facebookincubator/go-belt"
"github.com/facebookincubator/go-belt/tool/logger"
"github.com/xaionaro-go/lockmap"
"github.com/xaionaro-go/streamctl/pkg/encoder"
"github.com/xaionaro-go/streamctl/pkg/observability"
"github.com/xaionaro-go/streamctl/pkg/recoder"
"github.com/xaionaro-go/streamctl/pkg/secret"
"github.com/xaionaro-go/streamctl/pkg/streamcontrol/youtube"
"github.com/xaionaro-go/streamctl/pkg/streamd/memoize"
@@ -40,17 +40,17 @@ type StreamForwards struct {
DestinationStreamingLocker *lockmap.LockMap
ActiveStreamForwardings map[ForwardingKey]*ActiveStreamForwarding
StreamDestinations []types.StreamDestination
RecoderFactory recoder.Factory
EncoderFactory encoder.Factory
}
func NewStreamForwards(
s StreamServer,
recoderFactory recoder.Factory,
encoderFactory encoder.Factory,
pc types.PlatformsController,
) *StreamForwards {
return &StreamForwards{
StreamServer: s,
RecoderFactory: recoderFactory,
EncoderFactory: encoderFactory,
PlatformsController: pc,
DestinationStreamingLocker: lockmap.NewLockMap(),
ActiveStreamForwardings: map[ForwardingKey]*ActiveStreamForwarding{},

View File

@@ -16,10 +16,10 @@ type VideoConvertConfig struct {
type VideoTrackConfig struct {
InputVideoTrackIDs []uint
RecodeVideoConfig
EncodeVideoConfig
}
type RecodeVideoConfig struct {
type EncodeVideoConfig struct {
Enable bool `json:"enable,omitempty" yaml:"enable,omitempty"`
FlipV bool `json:"flip_v,omitempty" yaml:"flip_v,omitempty"`
FlipH bool `json:"flip_h,omitempty" yaml:"flip_h,omitempty"`
@@ -29,7 +29,7 @@ type RecodeVideoConfig struct {
Quality VideoQuality `json:"quality,omitempty" yaml:"quality,omitempty"`
}
func (c *RecodeVideoConfig) UnmarshalJSON(b []byte) (_err error) {
func (c *EncodeVideoConfig) UnmarshalJSON(b []byte) (_err error) {
c.Quality = videoQualitySerializable{}
err := json.Unmarshal(b, c)
if err != nil {
@@ -44,7 +44,7 @@ func (c *RecodeVideoConfig) UnmarshalJSON(b []byte) (_err error) {
return nil
}
func (c *RecodeVideoConfig) UnmarshalYAML(b []byte) (_err error) {
func (c *EncodeVideoConfig) UnmarshalYAML(b []byte) (_err error) {
c.Quality = videoQualitySerializable{}
err := yaml.Unmarshal(b, c)
if err != nil {
@@ -61,16 +61,16 @@ func (c *RecodeVideoConfig) UnmarshalYAML(b []byte) (_err error) {
type AudioTrackConfig struct {
InputAudioTrackIDs []uint
Recode RecodeAudioConfig
Encode EncodeAudioConfig
}
type RecodeAudioConfig struct {
type EncodeAudioConfig struct {
Enable bool `json:"enable,omitempty" yaml:"enable,omitempty"`
Codec AudioCodec `json:"codec,omitempty" yaml:"codec,omitempty"`
Quality AudioQuality `json:"quality,omitempty" yaml:"quality,omitempty"`
}
func (c *RecodeAudioConfig) UnmarshalJSON(b []byte) (_err error) {
func (c *EncodeAudioConfig) UnmarshalJSON(b []byte) (_err error) {
c.Quality = audioQualitySerializable{}
err := json.Unmarshal(b, c)
if err != nil {
@@ -85,7 +85,7 @@ func (c *RecodeAudioConfig) UnmarshalJSON(b []byte) (_err error) {
return nil
}
func (c *RecodeAudioConfig) UnmarshalYAML(b []byte) (_err error) {
func (c *EncodeAudioConfig) UnmarshalYAML(b []byte) (_err error) {
c.Quality = audioQualitySerializable{}
err := yaml.Unmarshal(b, c)
if err != nil {

View File

@@ -127,7 +127,7 @@ func (r *speechRecognizer) addTranscript(
return nil
}
func (r *speechRecognizer) Erender(
func (r *speechRecognizer) render(
ctx context.Context,
) {
logger.Debugf(ctx, "render(ctx)")