mirror of
https://github.com/xaionaro-go/streamctl.git
synced 2025-10-20 22:19:25 +08:00
Rename "recoder" to "encoder"
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
@@ -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,
|
@@ -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,
|
@@ -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 {
|
19
pkg/encoder/.wip/livego/recoder_factory.go
Normal file
19
pkg/encoder/.wip/livego/recoder_factory.go
Normal 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
|
||||
}
|
@@ -1,3 +1,3 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
type CodecName string
|
@@ -1,3 +1,3 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
type Config struct{}
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
type Decoder interface {
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
type HardwareDeviceTypeName string
|
||||
|
@@ -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)
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
import (
|
||||
"io"
|
@@ -1,3 +1,3 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
type InputConfig struct{}
|
@@ -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
|
||||
}
|
@@ -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)
|
||||
}
|
@@ -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
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
import (
|
||||
"github.com/asticode/go-astiav"
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
import (
|
||||
"context"
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
import (
|
||||
"context"
|
@@ -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,
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
import (
|
||||
"time"
|
@@ -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
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
import (
|
||||
"github.com/asticode/go-astiav"
|
@@ -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
|
37
pkg/encoder/libav/encoder_factory.go
Normal file
37
pkg/encoder/libav/encoder_factory.go
Normal 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
|
||||
}
|
78
pkg/encoder/libav/safeencoder/encoder.go
Normal file
78
pkg/encoder/libav/safeencoder/encoder.go
Normal 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
|
||||
}
|
5
pkg/encoder/libav/safeencoder/grpc/Makefile
Normal file
5
pkg/encoder/libav/safeencoder/grpc/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
all: go
|
||||
|
||||
go:
|
||||
protoc --go_out=. --go-grpc_out=. encoder.proto
|
@@ -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 {}
|
File diff suppressed because it is too large
Load Diff
@@ -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",
|
||||
}
|
@@ -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
|
@@ -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
|
@@ -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
|
||||
}
|
@@ -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)
|
27
pkg/encoder/libav/safeencoder/process/client/logger.go
Normal file
27
pkg/encoder/libav/safeencoder/process/client/logger.go
Normal 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
|
||||
}
|
||||
}
|
@@ -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))
|
@@ -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
|
||||
}
|
@@ -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")
|
||||
}
|
29
pkg/encoder/libav/safeencoder/process/server/logger.go
Normal file
29
pkg/encoder/libav/safeencoder/process/server/logger.go
Normal 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
|
||||
}
|
||||
}
|
@@ -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{})
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
import (
|
||||
"io"
|
@@ -1,3 +1,3 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
type OutputConfig struct{}
|
@@ -1,4 +1,4 @@
|
||||
package recoder
|
||||
package encoder
|
||||
|
||||
type Stats struct {
|
||||
BytesCountRead uint64
|
@@ -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
|
||||
|
11
pkg/encoder/xaionaro-go-rtmp/encoder_factory.go
Normal file
11
pkg/encoder/xaionaro-go-rtmp/encoder_factory.go
Normal 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{}
|
||||
}
|
@@ -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)
|
@@ -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 {
|
@@ -11,5 +11,5 @@ func NewStreamForwards(
|
||||
s StreamServer,
|
||||
platformsController types.PlatformsController,
|
||||
) *StreamForwards {
|
||||
return streamforward.NewStreamForwards(s, NewRecoderFactory(), platformsController)
|
||||
return streamforward.NewStreamForwards(s, NewEncoderFactory(), platformsController)
|
||||
}
|
@@ -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,
|
@@ -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)
|
||||
}
|
||||
|
@@ -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()
|
||||
|
@@ -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")
|
||||
|
@@ -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
|
||||
}
|
@@ -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
|
||||
}
|
@@ -1,5 +0,0 @@
|
||||
|
||||
all: go
|
||||
|
||||
go:
|
||||
protoc --go_out=. --go-grpc_out=. recoder.proto
|
@@ -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",
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
||||
}
|
@@ -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
|
||||
}
|
@@ -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{}
|
||||
}
|
@@ -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)
|
||||
}
|
||||
|
@@ -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,
|
||||
)
|
||||
}
|
||||
|
@@ -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"
|
||||
|
@@ -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,
|
||||
|
@@ -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{},
|
||||
|
@@ -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 {
|
||||
|
@@ -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)")
|
||||
|
Reference in New Issue
Block a user