Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/service/live/rtc/internal/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/conf:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/net/trace:go_default_library",
"//vendor/github.com/BurntSushi/toml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,90 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/conf"
"go-common/library/database/sql"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/verify"
"go-common/library/net/trace"
"github.com/BurntSushi/toml"
)
var (
confPath string
client *conf.Client
// Conf config
Conf = &Config{}
)
// Config .
type Config struct {
Log *log.Config
BM *bm.ServerConfig
Verify *verify.Config
Tracer *trace.Config
Redis *redis.Config
Memcache *memcache.Config
MySQL *sql.Config
Ecode *ecode.Config
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init init conf
func Init() error {
if confPath != "" {
return local()
}
return remote()
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
// Stupid codediscard it
//log.Info("config reload")
//if load() != nil {
// log.Error("config reload error (%v)", err)
//}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["dao.go"],
importpath = "go-common/app/service/live/rtc/internal/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/rtc/internal/conf:go_default_library",
"//app/service/live/rtc/internal/model:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,219 @@
package dao
import (
"context"
"go-common/app/service/live/rtc/internal/model"
"go-common/library/cache/redis"
"time"
"go-common/app/service/live/rtc/internal/conf"
xsql "go-common/library/database/sql"
)
// Dao dao
type Dao struct {
c *conf.Config
//mc *memcache.Pool
redis *redis.Pool
db *xsql.DB
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
redis: redis.NewPool(c.Redis),
db: xsql.NewMySQL(c.MySQL),
}
return
}
// Close close the resource.
func (d *Dao) Close() {
//d.mc.Close()
d.redis.Close()
d.db.Close()
}
// Ping dao ping
func (d *Dao) Ping(ctx context.Context) error {
// TODO: add mc,redis... if you use
return d.db.Ping(ctx)
}
func (d *Dao) GetMediaSource(ctx context.Context, channelID uint64) ([]*model.RtcMediaSource, error) {
sql := "SELECT `id`,`channel_id`,`user_id`,`type`,`codec`,`media_specific` FROM `rtc_media_source` WHERE `channel_id` = ? AND `status` = 0"
stmt := d.db.Prepared(sql)
defer stmt.Close()
rows, err := stmt.Query(ctx, channelID)
if err != nil {
return nil, err
}
defer rows.Close()
source := make([]*model.RtcMediaSource, 0)
for rows.Next() {
s := &model.RtcMediaSource{}
if err = rows.Scan(&s.SourceID, &s.ChannelID, &s.UserID, &s.Type, &s.Codec, &s.MediaSpecific); err != nil {
return nil, err
}
source = append(source, s)
}
return source, nil
}
func (d *Dao) CreateCall(ctx context.Context, call *model.RtcCall) (uint32, error) {
sql := "INSERT INTO `rtc_call`(`user_id`,`channel_id`,`version`,`token`,`join_time`,`leave_time`,`status`) VALUES(?,?,?,?,?,?,?)"
stmt := d.db.Prepared(sql)
defer stmt.Close()
r, err := stmt.Exec(ctx, call.UserID, call.ChannelID, call.Version, call.Token, call.JoinTime, call.LeaveTime, call.Status)
if err != nil {
return 0, err
}
id, err := r.LastInsertId()
if err != nil {
return 0, err
}
call.CallID = uint32(id)
return call.CallID, nil
}
func (d *Dao) UpdateCallStatus(ctx context.Context, channelID uint64, callID uint32, userID uint64, leave time.Time, status uint8) error {
sql := "UPDATE `rtc_call` SET `leave_time` = ?,`status` = ? WHERE `id` = ? AND `user_id` = ? LIMIT 1"
stmt := d.db.Prepared(sql)
defer stmt.Close()
_, err := stmt.Exec(ctx, leave, status, callID, userID)
if err != nil {
return err
}
return nil
}
func (d *Dao) UpdateMediaSourceStatus(ctx context.Context, channelID uint64, callID uint32, userID uint64, status uint8) error {
sql := "UPDATE `rtc_media_source` SET `status` = ? WHERE `call_id` = ? AND `channel_id` = ? AND `user_id` = ?"
stmt := d.db.Prepared(sql)
defer stmt.Close()
_, err := stmt.Exec(ctx, status, callID, channelID, userID)
if err != nil {
return err
}
return nil
}
func (d *Dao) CreateMediaSource(ctx context.Context, source *model.RtcMediaSource) (uint32, error) {
sql := "INSERT INTO `rtc_media_source`(`channel_id`,`user_id`,`type`,`codec`,`media_specific`,`status`) VALUES(?,?,?,?,?,?)"
stmt := d.db.Prepared(sql)
defer stmt.Close()
r, err := stmt.Exec(ctx, source.ChannelID, source.UserID, source.Type, source.Codec, source.MediaSpecific, source.Status)
if err != nil {
return 0, err
}
id, err := r.LastInsertId()
if err != nil {
return 0, err
}
return uint32(id), nil
}
func (d *Dao) CreateMediaPublish(ctx context.Context, publish *model.RtcMediaPublish) error {
mixConfigSql := "REPLACE INTO `rtc_mix_config`(`call_id`,`config`) VALUES(?,?)"
mixConfigStmt := d.db.Prepared(mixConfigSql)
defer mixConfigStmt.Close()
var err error
mixConfigResult, err := mixConfigStmt.Exec(ctx, publish.CallID, publish.MixConfig)
if err != nil {
return err
}
_, err = mixConfigResult.LastInsertId()
if err != nil {
return err
}
publishSql := "REPLACE INTO `rtc_media_publish`(`call_id`,`channel_id`,`user_id`,`switch`,`width`,`height`,`frame_rate`,`video_codec`,`video_profile`,`channel`,`sample_rate`,`audio_codec`,`bitrate`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)"
publishStmt := d.db.Prepared(publishSql)
defer publishStmt.Close()
_, err = publishStmt.Exec(ctx, publish.CallID, publish.ChannelID, publish.UserID, publish.Switch,
publish.Width, publish.Height, publish.FrameRate, publish.VideoCodec, publish.VideoProfile,
publish.Channel, publish.SampleRate, publish.AudioCodec, publish.Bitrate)
if err != nil {
return err
}
return nil
}
func (d *Dao) GetMediaPublishConfig(ctx context.Context, channelID uint64, callID uint32) (*model.RtcMediaPublish, error) {
publishSql := "SELECT `user_id`,`switch`,`width`,`height`,`frame_rate`,`video_codec`,`video_profile`,`channel`,`sample_rate`,`audio_codec`,`bitrate`,`mix_config_id` FROM `rtc_media_publish` WHERE `call_id` = ? AND `channel_id` = ? LIMIT 1"
publishStmt := d.db.Prepared(publishSql)
defer publishStmt.Close()
publishRow := publishStmt.QueryRow(ctx, callID, channelID)
var publish model.RtcMediaPublish
var mixConfigID uint32
if err := publishRow.Scan(&publish.UserID, &publish.Switch, &publish.Width, &publish.Height, &publish.FrameRate,
&publish.VideoCodec, &publish.VideoProfile, &publish.Channel, &publish.SampleRate,
&publish.AudioCodec, &publish.Bitrate, &mixConfigID); err != nil {
return nil, err
}
mixConfigSql := "SELECT `config` FROM `rtc_mix_config` WHERE `id` = ? "
mixConfigStmt := d.db.Prepared(mixConfigSql)
defer mixConfigStmt.Close()
mixConfigRow := mixConfigStmt.QueryRow(ctx, mixConfigID)
if err := mixConfigRow.Scan(&publish.MixConfig); err != nil {
return nil, err
}
return &publish, nil
}
func (d *Dao) UpdateMediaPublishConfig(ctx context.Context, channelID uint64, callID uint32, config string) error {
sql := "UPDATE `rtc_mix_config` SET `config` = ? WHERE `call_id` = ? LIMIT 1"
stmt := d.db.Prepared(sql)
defer stmt.Close()
_, err := stmt.Exec(ctx, config, callID)
if err != nil {
return err
}
return nil
}
func (d *Dao) TerminateStream(ctx context.Context, channelID uint64, callID uint32) error {
sql := "UPDATE `rtc_media_publish` SET `switch` = 0 WHERE `call_id` = ? LIMIT 1"
stmt := d.db.Prepared(sql)
defer stmt.Close()
_, err := stmt.Exec(ctx, callID)
if err != nil {
return err
}
return nil
}
func (d *Dao) GetChannelIP(ctx context.Context, channelID uint64) ([]string, error) {
sql := "SELECT `ip` FROM `rtc_call` WHERE `channel_id` = ? AND `status` = 0"
stmt := d.db.Prepared(sql)
defer stmt.Close()
rows, err := stmt.Query(ctx, channelID)
if err != nil {
return nil, err
}
defer rows.Close()
result := make([]string, 0)
for rows.Next() {
var ip string
if err = rows.Scan(&ip); err != nil {
return nil, err
}
result = append(result, ip)
}
return result, nil
}
func (d *Dao) GetToken(ctx context.Context, channelID uint64, callID uint32) (string, error) {
sql := "SELECT `token` FROM `rtc_call` WHERE `id` = ? AND `channel_id` = ?"
stmt := d.db.Prepared(sql)
defer stmt.Close()
row := stmt.QueryRow(ctx, callID, channelID)
var token string
err := row.Scan(&token)
if err == xsql.ErrNoRows {
err = nil
}
return token, err
}

View File

@@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["model.go"],
importpath = "go-common/app/service/live/rtc/internal/model",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,49 @@
package model
import "time"
type RtcMediaSource struct {
SourceID uint32
ChannelID uint64
UserID uint64
Type uint8
Codec string
MediaSpecific string
Status uint8
}
type RtcChannel struct {
ChannelID uint64
OwnerUserID uint64
Type uint8
Status uint8
Cluster string
}
type RtcCall struct {
CallID uint32
UserID uint64
ChannelID uint64
Version uint32
Token string
Status uint8
JoinTime time.Time
LeaveTime time.Time
}
type RtcMediaPublish struct {
UserID uint64
CallID uint32
ChannelID uint64
Switch uint8
Width uint32
Height uint32
FrameRate uint8
VideoCodec string
VideoProfile string
Channel uint8
SampleRate uint32
AudioCodec string
Bitrate uint32
MixConfig string
}

View File

@@ -0,0 +1,34 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["server.go"],
importpath = "go-common/app/service/live/rtc/internal/server/grpc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/rtc/api/v1:go_default_library",
"//app/service/live/rtc/internal/conf:go_default_library",
"//app/service/live/rtc/internal/service/v1:go_default_library",
"//library/net/rpc/warden:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,20 @@
package grpc
import (
v1pb "go-common/app/service/live/rtc/api/v1"
"go-common/app/service/live/rtc/internal/conf"
v1srv "go-common/app/service/live/rtc/internal/service/v1"
"go-common/library/net/rpc/warden"
)
// TODO
func New(c *conf.Config) *warden.Server {
ws := warden.NewServer(nil)
v1pb.RegisterRtcServer(ws.Server(), v1srv.NewRtcService(c))
ws, err := ws.Start()
if err != nil {
panic(err)
}
return ws
}

View File

@@ -0,0 +1,37 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["http.go"],
importpath = "go-common/app/service/live/rtc/internal/server/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/rtc/api/v1:go_default_library",
"//app/service/live/rtc/internal/conf:go_default_library",
"//app/service/live/rtc/internal/service:go_default_library",
"//app/service/live/rtc/internal/service/v1:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,55 @@
package http
import (
v1pb "go-common/app/service/live/rtc/api/v1"
"go-common/app/service/live/rtc/internal/conf"
"go-common/app/service/live/rtc/internal/service"
v1srv "go-common/app/service/live/rtc/internal/service/v1"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/verify"
"net/http"
)
var (
vfy *verify.Verify
svc *service.Service
)
// Init init
func Init(c *conf.Config, s *service.Service) {
svc = s
vfy = verify.New(c.Verify)
engine := bm.DefaultServer(c.BM)
route(engine)
if err := engine.Start(); err != nil {
log.Error("bm Start error(%v)", err)
panic(err)
}
}
func route(e *bm.Engine) {
e.Ping(ping)
e.Register(register)
g := e.Group("/x/rtc")
{
g.GET("/start", vfy.Verify, howToStart)
}
v1pb.RegisterRtcBMServer(e, v1srv.NewRtcService(conf.Conf))
}
func ping(ctx *bm.Context) {
if err := svc.Ping(ctx); err != nil {
log.Error("ping error(%v)", err)
ctx.AbortWithStatus(http.StatusServiceUnavailable)
}
}
func register(c *bm.Context) {
c.JSON(map[string]interface{}{}, nil)
}
// example for http request handler
func howToStart(c *bm.Context) {
c.String(0, "Golang 大法好 !!!")
}

View File

@@ -0,0 +1,39 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"dispatch.go",
"service.go",
"tool.go",
],
importpath = "go-common/app/service/live/rtc/internal/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/rtc/internal/conf:go_default_library",
"//app/service/live/rtc/internal/dao:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/service/live/rtc/internal/service/v1:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,15 @@
package service
type Dispatcher struct {
cache map[uint64]string
}
func NewDispatcher() *Dispatcher {
return &Dispatcher{
cache: make(map[uint64]string),
}
}
func (d *Dispatcher) AccessNode(channelID uint64) (string, error) {
return "127.0.0.1", nil
}

View File

@@ -0,0 +1,33 @@
package service
import (
"context"
"go-common/app/service/live/rtc/internal/conf"
"go-common/app/service/live/rtc/internal/dao"
)
// Service struct
type Service struct {
c *conf.Config
dao *dao.Dao
}
// New init
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: dao.New(c),
}
return s
}
// Ping Service
func (s *Service) Ping(ctx context.Context) (err error) {
return s.dao.Ping(ctx)
}
// Close Service
func (s *Service) Close() {
s.dao.Close()
}

View File

@@ -0,0 +1,29 @@
package service
import (
"bytes"
"math/rand"
"time"
)
type Tool struct {
rnd *rand.Rand
dict []byte
}
func NewTool() *Tool {
t := &Tool{
rnd: rand.New(rand.NewSource(time.Now().UnixNano())),
dict: []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
}
return t
}
func (t *Tool) RandomString(length int) string {
var result bytes.Buffer
result.Grow(length)
for i := 0; i < length; i++ {
result.WriteByte(t.dict[t.rnd.Intn(len(t.dict))])
}
return result.String()
}

View File

@@ -0,0 +1,37 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["rtc.go"],
importpath = "go-common/app/service/live/rtc/internal/service/v1",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/live/rtc/api/v1:go_default_library",
"//app/service/live/rtc/internal/conf:go_default_library",
"//app/service/live/rtc/internal/dao:go_default_library",
"//app/service/live/rtc/internal/model:go_default_library",
"//app/service/live/rtc/internal/service:go_default_library",
"//library/cache/redis:go_default_library",
"//library/log:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,212 @@
package v1
import (
"context"
"strings"
"time"
v1pb "go-common/app/service/live/rtc/api/v1"
"go-common/app/service/live/rtc/internal/conf"
"go-common/app/service/live/rtc/internal/dao"
"go-common/app/service/live/rtc/internal/model"
"go-common/app/service/live/rtc/internal/service"
"go-common/library/cache/redis"
"go-common/library/log"
)
// RtcService struct
type RtcService struct {
conf *conf.Config
// optionally add other properties here, such as dao
dao *dao.Dao
redis.Conn
tool *service.Tool
dispatch *service.Dispatcher
}
//NewRtcService init
func NewRtcService(c *conf.Config) (s *RtcService) {
s = &RtcService{
conf: c,
dao: dao.New(c),
tool: service.NewTool(),
}
return s
}
// JoinChannel implementation
func (s *RtcService) JoinChannel(ctx context.Context, req *v1pb.JoinChannelRequest) (resp *v1pb.JoinChannelResponse, err error) {
resp = &v1pb.JoinChannelResponse{}
call := &model.RtcCall{
UserID: req.UserId,
ChannelID: req.ChannelId,
Version: req.ProtoVersion,
Token: s.tool.RandomString(4),
Status: 0,
JoinTime: time.Now(),
LeaveTime: time.Unix(0, 0),
}
callID, err := s.dao.CreateCall(ctx, call)
if err != nil {
return nil, err
}
resp.CallId = callID
resp.Token = call.Token
for _, mediaSource := range req.Source {
ms := &model.RtcMediaSource{
ChannelID: req.ChannelId,
UserID: req.UserId,
Type: uint8(mediaSource.Type),
Codec: mediaSource.Codec,
MediaSpecific: mediaSource.MediaSpecific,
Status: 0,
}
ssrc, err := s.dao.CreateMediaSource(ctx, ms)
if err != nil {
return nil, err
}
mediaSource.Ssrc = ssrc
mediaSource.UserId = req.UserId
resp.Source = append(resp.Source, mediaSource)
}
return resp, nil
}
// LeaveChannel implementation
func (s *RtcService) LeaveChannel(ctx context.Context, req *v1pb.LeaveChannelRequest) (resp *v1pb.LeaveChannelResponse, err error) {
resp = &v1pb.LeaveChannelResponse{}
if e := s.dao.UpdateCallStatus(context.Background(), req.ChannelId, req.CallId, req.UserId, time.Now(), 1); e != nil {
log.Error("[LeaveChannel]UpdateCallStatus ChannelID:%d,CallID:%d,UserID:%d,error:%v", req.ChannelId, req.CallId, req.UserId, e)
}
if e := s.dao.UpdateMediaSourceStatus(context.Background(), req.ChannelId, req.CallId, req.UserId, 1); e != nil {
log.Error("[LeaveChannel]UpdateMediaSourceStatus ChannelID:%d,CallID:%d,UserID:%d,error:%v", req.ChannelId, req.CallId, req.UserId, e)
}
return resp, nil
}
// PublishStream implementation
func (s *RtcService) PublishStream(ctx context.Context, req *v1pb.PublishStreamRequest) (resp *v1pb.PublishStreamResponse, err error) {
resp = &v1pb.PublishStreamResponse{}
if e := s.dao.CreateMediaPublish(ctx, &model.RtcMediaPublish{
UserID: req.UserId,
CallID: req.CallId,
ChannelID: req.ChannelId,
Switch: 1,
Width: req.EncoderConfig.Width,
Height: req.EncoderConfig.Height,
FrameRate: uint8(req.EncoderConfig.FrameRate),
VideoCodec: req.EncoderConfig.VideoCodec,
VideoProfile: req.EncoderConfig.VideoProfile,
Channel: uint8(req.EncoderConfig.Channel),
SampleRate: req.EncoderConfig.SampleRate,
AudioCodec: req.EncoderConfig.AudioCodec,
Bitrate: req.EncoderConfig.Bitrate,
MixConfig: req.MixConfig,
}); e != nil {
return nil, e
}
return resp, nil
}
// TerminateStream implementation
func (s *RtcService) TerminateStream(ctx context.Context, req *v1pb.TerminateStreamRequest) (resp *v1pb.TerminateStreamResponse, err error) {
resp = &v1pb.TerminateStreamResponse{}
if e := s.dao.TerminateStream(ctx, req.ChannelId, req.CallId); e != nil {
return nil, e
}
return resp, nil
}
// Channel implementation
func (s *RtcService) Channel(ctx context.Context, req *v1pb.ChannelRequest) (resp *v1pb.ChannelResponse, err error) {
resp = &v1pb.ChannelResponse{}
mediaSource, err := s.dao.GetMediaSource(ctx, req.ChannelId)
if err != nil {
return nil, err
}
for _, s := range mediaSource {
var mediaType v1pb.MediaSource_MediaType
switch s.Type {
case 1:
mediaType = v1pb.MediaSource_VIDEO
case 2:
mediaType = v1pb.MediaSource_AUDIO
case 3:
mediaType = v1pb.MediaSource_DATA
case 4:
mediaType = v1pb.MediaSource_SMALL_VIDEO
default:
mediaType = v1pb.MediaSource_OTHER
}
resp.MediaSource = append(resp.MediaSource, &v1pb.MediaSource{
Type: mediaType,
Codec: s.Codec,
MediaSpecific: s.MediaSpecific,
Ssrc: s.SourceID,
UserId: s.UserID,
})
}
resp.Server, err = s.dispatch.AccessNode(req.ChannelId)
if err != nil {
return nil, err
}
//TODO: Read this value from Config
resp.TcpPort = 2247
resp.UdpPort = 2248
return resp, nil
}
// Stream implementation
func (s *RtcService) Stream(ctx context.Context, req *v1pb.StreamRequest) (resp *v1pb.StreamResponse, err error) {
resp = &v1pb.StreamResponse{}
publish, err := s.dao.GetMediaPublishConfig(ctx, req.ChannelId, req.CallId)
if err != nil {
return nil, err
}
resp.MixConfig = publish.MixConfig
resp.EncoderConfig = &v1pb.EncoderConfig{
Width: publish.Width,
Height: publish.Height,
Bitrate: publish.Bitrate,
FrameRate: uint32(publish.FrameRate),
VideoCodec: publish.VideoCodec,
VideoProfile: publish.VideoProfile,
Channel: uint32(publish.Channel),
SampleRate: publish.SampleRate,
AudioCodec: publish.AudioCodec,
}
return resp, nil
}
// SetRtcConfig implementation
// `method:"POST"`
func (s *RtcService) SetRtcConfig(ctx context.Context, req *v1pb.SetRtcConfigRequest) (resp *v1pb.SetRtcConfigResponse, err error) {
resp = &v1pb.SetRtcConfigResponse{}
if e := s.dao.UpdateMediaPublishConfig(ctx, req.ChannelId, req.CallId, req.Config); e != nil {
return nil, e
}
return resp, nil
}
// VerifyToken implementation
// `method:"GET"`
func (s *RtcService) VerifyToken(ctx context.Context, req *v1pb.VerifyTokenRequest) (resp *v1pb.VerifyTokenResponse, err error) {
resp = &v1pb.VerifyTokenResponse{}
if strings.Compare(req.Token, "") == 0 {
resp.Pass = false
return resp, nil
}
token, e := s.dao.GetToken(ctx, req.ChannelId, req.CallId)
if e != nil {
return nil, e
}
if strings.Compare(token, req.Token) == 0 {
resp.Pass = true
} else {
resp.Pass = false
}
return resp, nil
}