Refactor transcode HTTP to gRPC

This commit is contained in:
banshan
2024-10-07 22:35:03 +08:00
parent 39f69441a7
commit 58859f5fbf
7 changed files with 980 additions and 75 deletions

View File

@@ -1,44 +1,21 @@
package plugin_transcode
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
"path"
"strconv"
"strings"
globalPB "m7s.live/m7s/v5/pb"
"m7s.live/m7s/v5/plugin/transcode/pb"
"m7s.live/m7s/v5/pkg/config"
)
type OverlayConfig struct {
OverlayStream string `json:"overlay_stream"` // 叠加流 可为空
OverlayRegion string `json:"region"` //x,y,w,h 可为空,所有区域
OverlayImage string `json:"image"` // 图片 base64 可为空 如果图片和视频流都有,则使用图片
OverlayPosition string `json:"overlay_position"` //位置 x,y
Text string `json:"text"` // 文字
TimeOffset int64 `json:"time_offset"` // 时间偏移
TimeFormat string `json:"time_format"` // 时间格式
FontName string `json:"font_name"` //字体文件名
FontSize string `json:"font_size"` //字体大小
FontColor string `json:"font_color"` // r,g,b 颜色
TextPosition string `json:"text_position"` //x,y 文字在图片上的位置
imagePath string `json:"-"`
}
type OnDemandTrans struct {
SrcStream string `json:"src_stream"` //原始流
DstStream string `json:"dst_stream"` //输出流
OverlayConfigs []*OverlayConfig `json:"overlay_config"`
Encodec string `json:"encodec"`
Decodec string `json:"decodec"`
Scale string `json:"scale"`
LogLevel string `json:"log_level"`
}
func createTmpImage(image string) (string, error) {
//通过前缀判断base64图片类型
@@ -84,8 +61,14 @@ func parseFontColor(FontColor string) (string, error) {
b, _ := strconv.Atoi(rgb[2])
FontColor = fmt.Sprintf(":fontcolor=#%02x%02x%02x", r, g, b)
return FontColor, nil
case 0:
FontColor = ":fontcolor=black"
case 1:
if rgb[0] == "" {
FontColor = ":fontcolor=white"
} else if strings.HasPrefix(rgb[0], "#") && len(rgb[0]) == 7 {
FontColor = ":fontcolor=" + rgb[0]
} else {
return "", fmt.Errorf("FontColor 格式不正确")
}
return FontColor, nil
default:
return "", fmt.Errorf("FontColor 格式不正确")
@@ -147,75 +130,77 @@ func parseCrop(cropString string) (string, error) {
return fmt.Sprintf("crop=%s:%s:%s:%s", x, y, w, h), nil
}
func (t *TranscodePlugin) api_transcode_start(w http.ResponseWriter, r *http.Request) {
//解析出 OverlayConfigs
var transReq OnDemandTrans
err := json.NewDecoder(r.Body).Decode(&transReq)
func (t *TranscodePlugin) Launch(ctx context.Context, transReq *pb.TransRequest) (response *globalPB.SuccessResponse, err error) {
response = &globalPB.SuccessResponse{}
defer func() {
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
response.Code = -1
response.Message = err.Error()
} else {
response.Code = 0
response.Message = "success"
}
}()
var (
filters []string
out string
conf string
)
inputs := []string{""}
var filters []string
lastOverlay := "[0:v]"
out := ""
//循环判断
var vIdx = 0
for _, overlayConfig := range transReq.OverlayConfigs {
if overlayConfig.OverlayImage == "" && overlayConfig.Text == "" && overlayConfig.OverlayStream == "" {
http.Error(w, "image_base64 and text is required", http.StatusBadRequest)
err = fmt.Errorf("image_base64 and text is required")
return
}
filePath, err := createTmpImage(overlayConfig.OverlayImage)
var filePath string
filePath, err = createTmpImage(overlayConfig.OverlayImage)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
overlayConfig.imagePath = filePath
overlayConfig.OverlayImage = filePath
// 将 r,g,b 颜色字符串转换为十六进制颜色
overlayConfig.FontColor, err = parseFontColor(overlayConfig.FontColor)
if err != nil {
http.Error(w, "FontColor 格式不正确", http.StatusBadRequest)
return
}
overlayConfig.FontName, err = parseFontFile(overlayConfig.FontName)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// 字体大小
overlayConfig.FontSize, err = parseFontSize(overlayConfig.FontSize)
if err != nil {
http.Error(w, "FontSize 格式不正确", http.StatusBadRequest)
return
}
//坐标
overlayConfig.OverlayPosition, err = parseCoordinates(overlayConfig.OverlayPosition)
if err != nil {
http.Error(w, "OverlayPosition 格式不正确", http.StatusBadRequest)
return
}
overlayConfig.OverlayRegion, err = parseCrop(overlayConfig.OverlayRegion)
if err != nil {
http.Error(w, "OverlayRegion 格式不正确", http.StatusBadRequest)
return
}
overlayConfig.TextPosition, err = parseCoordinates(overlayConfig.TextPosition)
if err != nil {
http.Error(w, "TextPosition 格式不正确", http.StatusBadRequest)
return
}
overlayConfig.TextPosition = ":" + overlayConfig.TextPosition
//[1:v]crop=400:300:10:10[overlay];
if overlayConfig.imagePath != "" {
inputs = append(inputs, overlayConfig.imagePath)
if overlayConfig.OverlayImage != "" {
inputs = append(inputs, overlayConfig.OverlayImage)
} else if overlayConfig.OverlayStream != "" {
inputs = append(inputs, overlayConfig.OverlayStream)
}
// 生成 filter_complex
if overlayConfig.imagePath != "" || overlayConfig.OverlayStream != "" {
if overlayConfig.OverlayImage != "" || overlayConfig.OverlayStream != "" {
vIdx++
if overlayConfig.OverlayRegion != "" {
filters = append(filters, fmt.Sprintf("[%d:v]%s[overlay%d]", vIdx, overlayConfig.OverlayRegion, vIdx))
@@ -252,18 +237,13 @@ func (t *TranscodePlugin) api_transcode_start(w http.ResponseWriter, r *http.Req
}
//把 overlayconfig 转为
// transformer := t.Meta.Transformer()
// transcode := transformer.(*transcode.Transformer)
var cfg config.Transform
// 解析URL路径
targetURL := transReq.DstStream
parsedURL, err := url.Parse(targetURL)
if err != nil {
http.Error(w, "无效的目标URL", http.StatusBadRequest)
err = fmt.Errorf("无效的目标URL: %s", err)
return
}
@@ -272,18 +252,29 @@ func (t *TranscodePlugin) api_transcode_start(w http.ResponseWriter, r *http.Req
// 去掉开头的斜杠
streamPath = strings.TrimPrefix(streamPath, "/")
conf := strings.Join(inputs, " -i ") + fmt.Sprintf(" %s ", transReq.LogLevel) + fmt.Sprintf(" -filter_complex %s ", strings.Join(filters, ";")) + fmt.Sprintf(" -map %s ", out) + transReq.Scale + transReq.Decodec
// 拼接 ffmpeg 命令
filterStr := ""
if len(filters) != 0 {
filterStr = fmt.Sprintf(" -filter_complex %s ", strings.Join(filters, ";")) + fmt.Sprintf(" -map %s ", out)
}
conf = strings.Join(inputs, " -i ") + fmt.Sprintf(" %s ", transReq.LogLevel) + fmt.Sprintf(" %s ", filterStr) + transReq.Scale + transReq.Decodec
cfg.Output = []config.TransfromOutput{
{
Target: targetURL,
StreamPath: streamPath,
//Conf: "-log_level debug -c:v copy -an",
Conf: conf,
},
}
t.Transform(transReq.SrcStream, cfg)
// fmt.Println(transcode, cfg)
// fmt.Println(conf)
w.Write([]byte("ok"))
return
}
func (t *TranscodePlugin) Close(ctx context.Context, closeReq *pb.CloseRequest) (response *globalPB.SuccessResponse, err error) {
response = &globalPB.SuccessResponse{}
if item, ok := t.Server.Transforms.Get(closeReq.DstStream); ok {
item.TransformJob.Stop(fmt.Errorf("manual closed"))
}
return
}

View File

@@ -52,7 +52,7 @@ func Test_parseCrop(t *testing.T) {
args: args{
cropString: "100,100,200,200",
},
want: "crop=100:100:200:200",
want: "crop=200:200:100:100",
},
}
for _, tt := range tests {
@@ -84,7 +84,7 @@ func Test_rgbToHex(t *testing.T) {
args: args{
FontColor: "255,255,255",
},
want: "#ffffff",
want: ":fontcolor=#ffffff",
},
}
for _, tt := range tests {

View File

@@ -1,20 +1,14 @@
package plugin_transcode
import (
"net/http"
"m7s.live/m7s/v5"
"m7s.live/m7s/v5/plugin/transcode/pb"
transcode "m7s.live/m7s/v5/plugin/transcode/pkg"
)
var _ = m7s.InstallPlugin[TranscodePlugin](transcode.NewTransform)
var _ = m7s.InstallPlugin[TranscodePlugin](transcode.NewTransform, pb.RegisterApiHandler, &pb.Api_ServiceDesc)
type TranscodePlugin struct {
pb.UnimplementedApiServer
m7s.Plugin
}
func (t *TranscodePlugin) RegisterHandler() map[string]http.HandlerFunc {
return map[string]http.HandlerFunc{
"/api/start": t.api_transcode_start,
}
}

View File

@@ -0,0 +1,468 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.34.2
// protoc v3.20.3
// source: transcode.proto
package pb
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
_ "google.golang.org/protobuf/types/known/emptypb"
pb "m7s.live/m7s/v5/pb"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type OverlayConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
OverlayStream string `protobuf:"bytes,1,opt,name=overlay_stream,json=overlayStream,proto3" json:"overlay_stream,omitempty"` // 叠加流 可为空
OverlayRegion string `protobuf:"bytes,2,opt,name=overlay_region,json=overlayRegion,proto3" json:"overlay_region,omitempty"` // x,y,w,h 可为空,所有区域
OverlayImage string `protobuf:"bytes,3,opt,name=overlay_image,json=overlayImage,proto3" json:"overlay_image,omitempty"` // 图片 base64 可为空 如果图片和视频流都有,则使用图片
OverlayPosition string `protobuf:"bytes,4,opt,name=overlay_position,json=overlayPosition,proto3" json:"overlay_position,omitempty"` // 位置 x,y
Text string `protobuf:"bytes,5,opt,name=text,proto3" json:"text,omitempty"` // 文字
TimeOffset int64 `protobuf:"varint,6,opt,name=time_offset,json=timeOffset,proto3" json:"time_offset,omitempty"` // 时间偏移
TimeFormat string `protobuf:"bytes,7,opt,name=time_format,json=timeFormat,proto3" json:"time_format,omitempty"` // 时间格式
FontName string `protobuf:"bytes,8,opt,name=font_name,json=fontName,proto3" json:"font_name,omitempty"` // 字体文件名
FontSize string `protobuf:"bytes,9,opt,name=font_size,json=fontSize,proto3" json:"font_size,omitempty"` // 字体大小
FontColor string `protobuf:"bytes,10,opt,name=font_color,json=fontColor,proto3" json:"font_color,omitempty"` // r,g,b 颜色
TextPosition string `protobuf:"bytes,11,opt,name=text_position,json=textPosition,proto3" json:"text_position,omitempty"` // x,y 文字在图片上的位置
}
func (x *OverlayConfig) Reset() {
*x = OverlayConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_transcode_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OverlayConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OverlayConfig) ProtoMessage() {}
func (x *OverlayConfig) ProtoReflect() protoreflect.Message {
mi := &file_transcode_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use OverlayConfig.ProtoReflect.Descriptor instead.
func (*OverlayConfig) Descriptor() ([]byte, []int) {
return file_transcode_proto_rawDescGZIP(), []int{0}
}
func (x *OverlayConfig) GetOverlayStream() string {
if x != nil {
return x.OverlayStream
}
return ""
}
func (x *OverlayConfig) GetOverlayRegion() string {
if x != nil {
return x.OverlayRegion
}
return ""
}
func (x *OverlayConfig) GetOverlayImage() string {
if x != nil {
return x.OverlayImage
}
return ""
}
func (x *OverlayConfig) GetOverlayPosition() string {
if x != nil {
return x.OverlayPosition
}
return ""
}
func (x *OverlayConfig) GetText() string {
if x != nil {
return x.Text
}
return ""
}
func (x *OverlayConfig) GetTimeOffset() int64 {
if x != nil {
return x.TimeOffset
}
return 0
}
func (x *OverlayConfig) GetTimeFormat() string {
if x != nil {
return x.TimeFormat
}
return ""
}
func (x *OverlayConfig) GetFontName() string {
if x != nil {
return x.FontName
}
return ""
}
func (x *OverlayConfig) GetFontSize() string {
if x != nil {
return x.FontSize
}
return ""
}
func (x *OverlayConfig) GetFontColor() string {
if x != nil {
return x.FontColor
}
return ""
}
func (x *OverlayConfig) GetTextPosition() string {
if x != nil {
return x.TextPosition
}
return ""
}
type TransRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SrcStream string `protobuf:"bytes,1,opt,name=src_stream,json=srcStream,proto3" json:"src_stream,omitempty"` // 原始流
DstStream string `protobuf:"bytes,2,opt,name=dst_stream,json=dstStream,proto3" json:"dst_stream,omitempty"` // 输出流
Encodec string `protobuf:"bytes,3,opt,name=encodec,proto3" json:"encodec,omitempty"`
Decodec string `protobuf:"bytes,4,opt,name=decodec,proto3" json:"decodec,omitempty"`
Scale string `protobuf:"bytes,5,opt,name=scale,proto3" json:"scale,omitempty"`
LogLevel string `protobuf:"bytes,6,opt,name=log_level,json=logLevel,proto3" json:"log_level,omitempty"`
OverlayConfigs []*OverlayConfig `protobuf:"bytes,7,rep,name=overlay_configs,json=overlayConfigs,proto3" json:"overlay_configs,omitempty"`
}
func (x *TransRequest) Reset() {
*x = TransRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_transcode_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *TransRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TransRequest) ProtoMessage() {}
func (x *TransRequest) ProtoReflect() protoreflect.Message {
mi := &file_transcode_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TransRequest.ProtoReflect.Descriptor instead.
func (*TransRequest) Descriptor() ([]byte, []int) {
return file_transcode_proto_rawDescGZIP(), []int{1}
}
func (x *TransRequest) GetSrcStream() string {
if x != nil {
return x.SrcStream
}
return ""
}
func (x *TransRequest) GetDstStream() string {
if x != nil {
return x.DstStream
}
return ""
}
func (x *TransRequest) GetEncodec() string {
if x != nil {
return x.Encodec
}
return ""
}
func (x *TransRequest) GetDecodec() string {
if x != nil {
return x.Decodec
}
return ""
}
func (x *TransRequest) GetScale() string {
if x != nil {
return x.Scale
}
return ""
}
func (x *TransRequest) GetLogLevel() string {
if x != nil {
return x.LogLevel
}
return ""
}
func (x *TransRequest) GetOverlayConfigs() []*OverlayConfig {
if x != nil {
return x.OverlayConfigs
}
return nil
}
type CloseRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
SrcStream string `protobuf:"bytes,1,opt,name=src_stream,json=srcStream,proto3" json:"src_stream,omitempty"` // 原始流
DstStream string `protobuf:"bytes,2,opt,name=dst_stream,json=dstStream,proto3" json:"dst_stream,omitempty"` // 输出流
}
func (x *CloseRequest) Reset() {
*x = CloseRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_transcode_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CloseRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CloseRequest) ProtoMessage() {}
func (x *CloseRequest) ProtoReflect() protoreflect.Message {
mi := &file_transcode_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CloseRequest.ProtoReflect.Descriptor instead.
func (*CloseRequest) Descriptor() ([]byte, []int) {
return file_transcode_proto_rawDescGZIP(), []int{2}
}
func (x *CloseRequest) GetSrcStream() string {
if x != nil {
return x.SrcStream
}
return ""
}
func (x *CloseRequest) GetDstStream() string {
if x != nil {
return x.DstStream
}
return ""
}
var File_transcode_proto protoreflect.FileDescriptor
var file_transcode_proto_rawDesc = []byte{
0x0a, 0x0f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x12, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x1a, 0x1c, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74,
0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x81, 0x03, 0x0a, 0x0d, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x61,
0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, 0x0e, 0x6f, 0x76, 0x65, 0x72, 0x6c,
0x61, 0x79, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0d, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x25,
0x0a, 0x0e, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x52,
0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79,
0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x76,
0x65, 0x72, 0x6c, 0x61, 0x79, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x6f, 0x76,
0x65, 0x72, 0x6c, 0x61, 0x79, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x50, 0x6f, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x05, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x69, 0x6d,
0x65, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a,
0x74, 0x69, 0x6d, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x69,
0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0a, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x66,
0x6f, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
0x66, 0x6f, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6f, 0x6e, 0x74,
0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x6f, 0x6e,
0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x6f, 0x6e, 0x74, 0x5f, 0x63, 0x6f,
0x6c, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x6f, 0x6e, 0x74, 0x43,
0x6f, 0x6c, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x6f, 0x73,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, 0x65, 0x78,
0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xf6, 0x01, 0x0a, 0x0c, 0x54, 0x72,
0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x72,
0x63, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
0x73, 0x72, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x73, 0x74,
0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64,
0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x6f,
0x64, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x63, 0x6f, 0x64,
0x65, 0x63, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x18, 0x04, 0x20,
0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x12, 0x14, 0x0a, 0x05,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x63, 0x61,
0x6c, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18,
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12,
0x41, 0x0a, 0x0f, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73,
0x63, 0x6f, 0x64, 0x65, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x52, 0x0e, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x73, 0x22, 0x4c, 0x0a, 0x0c, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x72, 0x63, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x72, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61,
0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x32, 0xbf, 0x01, 0x0a, 0x03, 0x61, 0x70, 0x69, 0x12, 0x5c, 0x0a, 0x06, 0x6c, 0x61, 0x75, 0x6e,
0x63, 0x68, 0x12, 0x17, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x54,
0x72, 0x61, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x6c,
0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22,
0x15, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f,
0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x12, 0x5a, 0x0a, 0x05, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x12,
0x17, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x43, 0x6c, 0x6f, 0x73,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61,
0x6c, 0x2e, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x74,
0x72, 0x61, 0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6c, 0x6f,
0x73, 0x65, 0x42, 0x25, 0x5a, 0x23, 0x6d, 0x37, 0x73, 0x2e, 0x6c, 0x69, 0x76, 0x65, 0x2f, 0x6d,
0x37, 0x73, 0x2f, 0x76, 0x35, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x74, 0x72, 0x61,
0x6e, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (
file_transcode_proto_rawDescOnce sync.Once
file_transcode_proto_rawDescData = file_transcode_proto_rawDesc
)
func file_transcode_proto_rawDescGZIP() []byte {
file_transcode_proto_rawDescOnce.Do(func() {
file_transcode_proto_rawDescData = protoimpl.X.CompressGZIP(file_transcode_proto_rawDescData)
})
return file_transcode_proto_rawDescData
}
var file_transcode_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_transcode_proto_goTypes = []any{
(*OverlayConfig)(nil), // 0: transcode.OverlayConfig
(*TransRequest)(nil), // 1: transcode.TransRequest
(*CloseRequest)(nil), // 2: transcode.CloseRequest
(*pb.SuccessResponse)(nil), // 3: global.SuccessResponse
}
var file_transcode_proto_depIdxs = []int32{
0, // 0: transcode.TransRequest.overlay_configs:type_name -> transcode.OverlayConfig
1, // 1: transcode.api.launch:input_type -> transcode.TransRequest
2, // 2: transcode.api.close:input_type -> transcode.CloseRequest
3, // 3: transcode.api.launch:output_type -> global.SuccessResponse
3, // 4: transcode.api.close:output_type -> global.SuccessResponse
3, // [3:5] is the sub-list for method output_type
1, // [1:3] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_transcode_proto_init() }
func file_transcode_proto_init() {
if File_transcode_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_transcode_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*OverlayConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_transcode_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*TransRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_transcode_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*CloseRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_transcode_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_transcode_proto_goTypes,
DependencyIndexes: file_transcode_proto_depIdxs,
MessageInfos: file_transcode_proto_msgTypes,
}.Build()
File_transcode_proto = out.File
file_transcode_proto_rawDesc = nil
file_transcode_proto_goTypes = nil
file_transcode_proto_depIdxs = nil
}

View File

@@ -0,0 +1,241 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: transcode.proto
/*
Package pb is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package pb
import (
"context"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join
func request_Api_Launch_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq TransRequest
var metadata runtime.ServerMetadata
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Launch(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Api_Launch_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq TransRequest
var metadata runtime.ServerMetadata
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Launch(ctx, &protoReq)
return msg, metadata, err
}
func request_Api_Close_0(ctx context.Context, marshaler runtime.Marshaler, client ApiClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CloseRequest
var metadata runtime.ServerMetadata
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Close(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Api_Close_0(ctx context.Context, marshaler runtime.Marshaler, server ApiServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CloseRequest
var metadata runtime.ServerMetadata
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Close(ctx, &protoReq)
return msg, metadata, err
}
// RegisterApiHandlerServer registers the http handlers for service Api to "mux".
// UnaryRPC :call ApiServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterApiHandlerFromEndpoint instead.
// GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
func RegisterApiHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ApiServer) error {
mux.Handle("POST", pattern_Api_Launch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/transcode.Api/Launch", runtime.WithHTTPPathPattern("/transcode/api/launch"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Api_Launch_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Api_Launch_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_Api_Close_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/transcode.Api/Close", runtime.WithHTTPPathPattern("/transcode/api/close"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Api_Close_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Api_Close_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterApiHandlerFromEndpoint is same as RegisterApiHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterApiHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.NewClient(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Errorf("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterApiHandler(ctx, mux, conn)
}
// RegisterApiHandler registers the http handlers for service Api to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterApiHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterApiHandlerClient(ctx, mux, NewApiClient(conn))
}
// RegisterApiHandlerClient registers the http handlers for service Api
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ApiClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ApiClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "ApiClient" to call the correct interceptors. This client ignores the HTTP middlewares.
func RegisterApiHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ApiClient) error {
mux.Handle("POST", pattern_Api_Launch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/transcode.Api/Launch", runtime.WithHTTPPathPattern("/transcode/api/launch"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Api_Launch_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Api_Launch_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_Api_Close_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
var err error
var annotatedContext context.Context
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/transcode.Api/Close", runtime.WithHTTPPathPattern("/transcode/api/close"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Api_Close_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_Api_Close_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Api_Launch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"transcode", "api", "launch"}, ""))
pattern_Api_Close_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"transcode", "api", "close"}, ""))
)
var (
forward_Api_Launch_0 = runtime.ForwardResponseMessage
forward_Api_Close_0 = runtime.ForwardResponseMessage
)

View File

@@ -0,0 +1,51 @@
syntax = "proto3";
import "google/api/annotations.proto";
import "google/protobuf/empty.proto";
import "global.proto";
package transcode;
option go_package="m7s.live/m7s/v5/plugin/transcode/pb";
service api {
rpc launch (TransRequest) returns (global.SuccessResponse) {
option (google.api.http) = {
post: "/transcode/api/launch"
body: "*"
};
}
rpc close (CloseRequest) returns (global.SuccessResponse) {
option (google.api.http) = {
post: "/transcode/api/close"
body: "*"
};
}
}
message OverlayConfig {
string overlay_stream = 1; // 叠加流 可为空
string overlay_region = 2; // x,y,w,h 可为空,所有区域
string overlay_image = 3; // 图片 base64 可为空 如果图片和视频流都有,则使用图片
string overlay_position = 4; // 位置 x,y
string text = 5; // 文字
int64 time_offset = 6; // 时间偏移
string time_format = 7; // 时间格式
string font_name = 8; // 字体文件名
string font_size = 9; // 字体大小
string font_color = 10; // r,g,b 颜色
string text_position = 11; // x,y 文字在图片上的位置
}
message TransRequest {
string src_stream = 1; // 原始流
string dst_stream = 2; // 输出流
string encodec = 3;
string decodec = 4;
string scale = 5;
string log_level = 6;
repeated OverlayConfig overlay_configs = 7;
}
message CloseRequest {
string src_stream = 1; // 原始流
string dst_stream = 2; // 输出流
}

View File

@@ -0,0 +1,160 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc v3.20.3
// source: transcode.proto
package pb
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
pb "m7s.live/m7s/v5/pb"
)
// 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.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
Api_Launch_FullMethodName = "/transcode.api/launch"
Api_Close_FullMethodName = "/transcode.api/close"
)
// ApiClient is the client API for Api 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 ApiClient interface {
Launch(ctx context.Context, in *TransRequest, opts ...grpc.CallOption) (*pb.SuccessResponse, error)
Close(ctx context.Context, in *CloseRequest, opts ...grpc.CallOption) (*pb.SuccessResponse, error)
}
type apiClient struct {
cc grpc.ClientConnInterface
}
func NewApiClient(cc grpc.ClientConnInterface) ApiClient {
return &apiClient{cc}
}
func (c *apiClient) Launch(ctx context.Context, in *TransRequest, opts ...grpc.CallOption) (*pb.SuccessResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(pb.SuccessResponse)
err := c.cc.Invoke(ctx, Api_Launch_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *apiClient) Close(ctx context.Context, in *CloseRequest, opts ...grpc.CallOption) (*pb.SuccessResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(pb.SuccessResponse)
err := c.cc.Invoke(ctx, Api_Close_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// ApiServer is the server API for Api service.
// All implementations must embed UnimplementedApiServer
// for forward compatibility.
type ApiServer interface {
Launch(context.Context, *TransRequest) (*pb.SuccessResponse, error)
Close(context.Context, *CloseRequest) (*pb.SuccessResponse, error)
mustEmbedUnimplementedApiServer()
}
// UnimplementedApiServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedApiServer struct{}
func (UnimplementedApiServer) Launch(context.Context, *TransRequest) (*pb.SuccessResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Launch not implemented")
}
func (UnimplementedApiServer) Close(context.Context, *CloseRequest) (*pb.SuccessResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Close not implemented")
}
func (UnimplementedApiServer) mustEmbedUnimplementedApiServer() {}
func (UnimplementedApiServer) testEmbeddedByValue() {}
// UnsafeApiServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to ApiServer will
// result in compilation errors.
type UnsafeApiServer interface {
mustEmbedUnimplementedApiServer()
}
func RegisterApiServer(s grpc.ServiceRegistrar, srv ApiServer) {
// If the following call pancis, it indicates UnimplementedApiServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&Api_ServiceDesc, srv)
}
func _Api_Launch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(TransRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ApiServer).Launch(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Api_Launch_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ApiServer).Launch(ctx, req.(*TransRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Api_Close_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CloseRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ApiServer).Close(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Api_Close_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ApiServer).Close(ctx, req.(*CloseRequest))
}
return interceptor(ctx, in, info, handler)
}
// Api_ServiceDesc is the grpc.ServiceDesc for Api service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Api_ServiceDesc = grpc.ServiceDesc{
ServiceName: "transcode.api",
HandlerType: (*ApiServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "launch",
Handler: _Api_Launch_Handler,
},
{
MethodName: "close",
Handler: _Api_Close_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "transcode.proto",
}