直播修改

master
kanade 5 years ago
parent 93466c76cc
commit 4be28a4b80

@ -6,6 +6,7 @@ import (
"live/app/common"
"live/app/lib"
"live/app/lib/back"
"live/app/lib/config"
"live/app/lib/recook"
"live/app/lib/tencent"
"live/app/lib/tools"
@ -90,6 +91,14 @@ func (l *Live) List(c *gin.Context) {
back.Suc(c, "操作成功", result)
}
// @Title live sdk License
func (l *Live) License(c *gin.Context) {
back.Suc(c, "操作成功", gin.H{
"key": config.Config.Section("tencent.live.license").Key("key").String(),
"licenseUrl": config.Config.Section("tencent.live.license").Key("licenseUrl").String(),
})
}
type liveInfo struct {
LiveItemId uint `json:"liveItemId"`
PushUrl string `json:"pushUrl"`
@ -107,8 +116,10 @@ type liveInfo struct {
func (l *Live) Info(c *gin.Context) {
userId := common.GetUserId(c)
liveRoom := (&live2.LiveRoom{}).GetLiveByUserId(userId)
userData := &user.UserData{}
udata := userData.GetByUserId(userId)
isFirst := 1
if liveRoom.Id > 0 {
if udata.LiveTreaty == 1 {
isFirst = 0
}
liveItem := (&live2.LiveItem{}).GetLiveItemIng(userId)
@ -165,6 +176,33 @@ func (l *Live) Info(c *gin.Context) {
back.Suc(c, "操作成功", reply)
}
// @Title 同意协议
func (l *Live) Agree(c *gin.Context) {
userId := common.GetUserId(c)
userDataModel := &user.UserData{}
udata := userDataModel.GetByUserId(userId)
if udata.Id > 0 {
if udata.LiveTreaty != user.LiveTreatyAgree {
row := userDataModel.Treaty(userId)
if row <= 0 {
back.Fail(c, "操作失败")
return
}
}
} else {
data := user.UserData{
UserId: userId,
LiveTreaty: user.LiveTreatyAgree,
}
userDataModel.Create(&data)
if data.Id <= 0 {
back.Fail(c, "操作失败")
return
}
}
back.Suc(c, "操作成功", "")
}
type userFolowLive struct {
Id uint `json:"id"`
UserId uint `json:"userId"`
@ -539,6 +577,28 @@ func (l *Live) Stop(c *gin.Context) {
back.Suc(c, "操作成功", result)
}
type argsTranscribe struct {
LiveItemId uint `json:"liveItemId" form:"liveItemId"`
}
// @Title 保存录制
func (l *Live) Transcribe(c *gin.Context) {
args := argsTranscribe{}
if err := tools.ParseParams(&args, c); err != nil {
back.Fail(c, err.Error())
return
}
if args.LiveItemId <= 0 {
back.Fail(c, "参数错误")
return
}
if err := live.LiveLogic.Transcribe(args.LiveItemId); err != nil {
back.Fail(c, err.Error())
return
}
back.Suc(c, "操作成功", "")
}
type argsUserData struct {
Identifiers []string `json:"identifiers" form:"identifiers"`
}

File diff suppressed because one or more lines are too long

@ -21,23 +21,22 @@ func init() {
if err != nil {
panic(err)
}
// 覆盖配置
for _, s := range asset.AssetNames() {
if err := asset.RestoreAsset(Config.WorkPath, s); err != nil {
log.Fatal("释放资源出错", err)
return
}
}
// 配置读取
Config.File, err = ini.Load(Config.WorkPath + "/config/app.ini")
if err != nil {
for _, s := range asset.AssetNames() {
if err := asset.RestoreAsset(Config.WorkPath, s); err != nil {
log.Fatal("释放资源出错", err)
return
}
}
Config.File, err = ini.Load(Config.WorkPath + "/config/app.ini")
if err != nil {
log.Fatal("配置文件读取失败err:", err)
return
}
log.Fatal("配置文件读取失败err:", err)
return
}
Config.ValueMapper = ExpandValueEnv
Config.RUNMODE = Config.Section("").Key("runmode").String()
log.Println(Config.RUNMODE)
if Config.RUNMODE != "" {
Config.Append(Config.WorkPath + "/config/app." + Config.RUNMODE + ".ini")
}

@ -20,6 +20,7 @@ const (
LiveGroupMsgTypeLiveStop = "LiveStop"
LiveGroupMsgTypeBuyGoods = "BuyGoods"
LiveGroupMsgTypeNotice = "Notice"
LiveGroupMsgTypePraise = "Praise"
)
var ImLogic = &im{}

@ -13,6 +13,7 @@ import (
"live/app/logic/goods"
live2 "live/app/model/live"
"live/app/model/user"
"log"
"strconv"
"time"
)
@ -47,6 +48,7 @@ func (l live) Start(userId uint, title, cover string, topic uint, goodsIds []uin
}
groupId := fmt.Sprintf("group_%d", userId)
if err = tencent.Im.AddLiveGroup(info.Identifier, "直播群", groupId); err != nil {
log.Println(err)
return LiveInfo{}, err
}
liveRoom = live2.LiveRoom{
@ -170,6 +172,27 @@ func (l *live) Stop(userId, liveItemId uint) error {
})
}
// @Title 直播视频录制
func (l *live) Transcribe(liveItemId uint) error {
liveItem := &live2.LiveItem{}
item := liveItem.FindById(liveItemId)
if item.TranscribeType != live2.LIVE_Transcribe_Type_none {
return nil
}
if item.FileId == "" {
row := liveItem.Transcribe(liveItemId, live2.LIVE_Transcribe_Type_ing)
if row <= 0 {
return errors.New("网络错误")
}
} else {
row := liveItem.Transcribe(liveItemId, live2.LIVE_Transcribe_Type_finish)
if row <= 0 {
return errors.New("网络错误")
}
}
return nil
}
type replyStopLiveInfo struct {
Nickname string `json:"nickname"`
HeadImgUrl string `json:"headImgUrl"`

@ -2,6 +2,7 @@ package live
import (
"errors"
"github.com/gin-gonic/gin"
"live/app/lib/config"
live2 "live/app/model/live"
"live/app/model/user"
@ -65,5 +66,11 @@ func (p *Praise) AddPraise(userId, liveItemId, praise uint) (err error) {
if row <= 0 {
return errors.New("点赞失败")
}
// 发送广播
ImLogic.SendLiveGroupMessage(info.RoomId, LiveGroupMsgTypePraise, gin.H{
"praise": trendPraise.Praise + praise,
"addPraise": praise,
})
return
}

@ -6,27 +6,33 @@ import (
)
const (
LIVE_STATUS_finish = 0
LIVE_STATUS_ing = 1
LIVE_STATUS_finish = 0 // 已完成直播
LIVE_STATUS_ing = 1 // 直播中
LIVE_Transcribe_Type_none = 0 // 不录制
LIVE_Transcribe_Type_ing = 1 // 录制中
LIVE_Transcribe_Type_finish = 2 // 录制完成
)
type LiveItem struct {
db.BaseModel
Id uint `gorm:"column:id" json:"id"`
UserId uint `gorm:"column:user_id" json:"userId"`
RoomId uint `gorm:"column:room_id" json:"roomId"`
MainGoodsId uint `gorm:"column:main_goods_id" json:"mainGoodsId"`
GoodsCount uint `gorm:"column:goods_count" json:"goodsCount"`
Title string `gorm:"column:title" json:"title"`
Cover string `gorm:"column:cover" json:"cover"`
Topic uint `gorm:"column:topic" json:"topic"`
Status int `gorm:"column:status" json:"status"`
CreatedAt formatime.Second `gorm:"column:created_at" json:"createdAt"`
UpdatedAt formatime.Second `gorm:"column:updated_at" json:"updatedAt"`
StartAt formatime.Second `gorm:"column:start_at" json:"startAt"`
EndAt formatime.Second `gorm:"column:end_at" json:"endAt"`
VideoUrl string `gorm:"column:video_url" json:"videoUrl"`
Fans uint `gorm:"column:fans" json:"fans"`
Id uint `gorm:"column:id" json:"id"`
UserId uint `gorm:"column:user_id" json:"userId"`
RoomId uint `gorm:"column:room_id" json:"roomId"`
MainGoodsId uint `gorm:"column:main_goods_id" json:"mainGoodsId"`
GoodsCount uint `gorm:"column:goods_count" json:"goodsCount"`
Title string `gorm:"column:title" json:"title"`
Cover string `gorm:"column:cover" json:"cover"`
Topic uint `gorm:"column:topic" json:"topic"`
Status int `gorm:"column:status" json:"status"`
CreatedAt formatime.Second `gorm:"column:created_at" json:"createdAt"`
UpdatedAt formatime.Second `gorm:"column:updated_at" json:"updatedAt"`
StartAt formatime.Second `gorm:"column:start_at" json:"startAt"`
EndAt formatime.Second `gorm:"column:end_at" json:"endAt"`
FileId string `gorm:"column:file_id" json:"fileId"`
VideoUrl string `gorm:"column:video_url" json:"videoUrl"`
Fans uint `gorm:"column:fans" json:"fans"`
TranscribeType int `gorm:"column:transcribe_type" json:"transcribeType"`
}
// 插入
@ -40,7 +46,7 @@ func (l *LiveItem) Create(liveItem *LiveItem) uint {
// @Title 当前直播列表
func (l *LiveItem) Lists(start, limit int) (result []LiveItem) {
l.GetDb().Model(&LiveItem{}).Offset(start).Limit(limit).Order("id desc").Find(&result)
l.GetDb().Model(&LiveItem{}).Where("status = ? or transcribe_type = ?", LIVE_STATUS_ing, LIVE_Transcribe_Type_finish).Offset(start).Limit(limit).Order("id desc").Find(&result)
return
}
@ -94,3 +100,8 @@ func (l *LiveItem) GetLiveItemIng(userId uint) (result LiveItem) {
l.GetDb().Model(&LiveItem{}).First(&result, "user_id = ? and `status` = ?", userId, LIVE_STATUS_ing)
return
}
// @Title 更改录播状态
func (l *LiveItem) Transcribe(liveItemId uint, transcribeType int) int64 {
return l.GetDb().Model(&LiveItem{}).Where("id = ?", liveItemId).Update("transcribe_type", transcribeType).RowsAffected
}

@ -5,13 +5,19 @@ import (
"live/app/lib/db"
)
const (
LiveTreatyNone = 0
LiveTreatyAgree = 1
)
type UserData struct {
db.BaseModel
Id uint `gorm:"column:id" json:"id"`
UserId uint `gorm:"column:user_id" json:"userId"`
Follows uint `gorm:"column:follows" json:"follows"`
Fans uint `gorm:"column:fans" json:"fans"`
Praise uint `gorm:"column:praise" json:"praise"`
Id uint `gorm:"column:id" json:"id"`
UserId uint `gorm:"column:user_id" json:"userId"`
Follows uint `gorm:"column:follows" json:"follows"`
Fans uint `gorm:"column:fans" json:"fans"`
Praise uint `gorm:"column:praise" json:"praise"`
LiveTreaty uint `gorm:"column:live_treaty" json:"liveTreaty"`
}
// 插入
@ -48,7 +54,7 @@ func (u *UserData) AddFollow(userId uint) int64 {
if userId == 0 {
return 0
}
rows := u.GetDb().Model(u).Where(UserData{UserId: userId}).Update("follows", gorm.Expr("follows + ?", 1)).RowsAffected
rows := u.GetDb().Model(u).Where("user_id = ?", userId).Update("follows", gorm.Expr("follows + ?", 1)).RowsAffected
if rows == 0 {
id := u.GetDb().Create(&UserData{
UserId: userId,
@ -66,7 +72,7 @@ func (u *UserData) CancelFollow(userId uint) int64 {
if userId == 0 {
return 0
}
return u.GetDb().Model(u).Where(&UserData{UserId: userId}).Update("follows", gorm.Expr("follows - ?", 1)).RowsAffected
return u.GetDb().Model(u).Where("user_id = ?", userId).Update("follows", gorm.Expr("follows - ?", 1)).RowsAffected
}
// @Title 会员新增粉丝
@ -74,7 +80,7 @@ func (u *UserData) AddFans(userId uint) int64 {
if userId == 0 {
return 0
}
rows := u.GetDb().Model(u).Where(&UserData{UserId: userId}).Update("fans", gorm.Expr("fans + ?", 1)).RowsAffected
rows := u.GetDb().Model(u).Where("user_id = ?", userId).Update("fans", gorm.Expr("fans + ?", 1)).RowsAffected
if rows == 0 {
id := u.GetDb().Create(&UserData{
UserId: userId,
@ -92,7 +98,7 @@ func (u *UserData) CancelFans(userId uint) int64 {
if userId == 0 {
return 0
}
return u.GetDb().Model(u).Where(&UserData{UserId: userId}).Update("fans", gorm.Expr("fans - ?", 1)).RowsAffected
return u.GetDb().Model(u).Where("user_id = ?", userId).Update("fans", gorm.Expr("fans - ?", 1)).RowsAffected
}
// @Title 会员新增赞
@ -100,7 +106,7 @@ func (u *UserData) AddPraise(userId, praise uint) int64 {
if userId == 0 {
return 0
}
rows := u.GetDb().Model(u).Where(&UserData{UserId: userId}).Update("praise", gorm.Expr("praise + ?", praise)).RowsAffected
rows := u.GetDb().Model(u).Where("user_id = ?", userId).Update("praise", gorm.Expr("praise + ?", praise)).RowsAffected
if rows == 0 {
id := u.GetDb().Create(&UserData{
UserId: userId,
@ -118,5 +124,13 @@ func (u *UserData) CancelPraise(userId uint) int64 {
if userId == 0 {
return 0
}
return u.GetDb().Model(u).Where(&UserData{UserId: userId}).Update("praise", gorm.Expr("praise - ?", 1)).RowsAffected
return u.GetDb().Model(u).Where("user_id = ?", userId).Update("praise", gorm.Expr("praise - ?", 1)).RowsAffected
}
// @Title 同意直播协议
func (u *UserData) Treaty(userId uint) int64 {
if userId == 0 {
return 0
}
return u.GetDb().Model(u).Where("user_id = ?", userId).Update("live_treaty", LiveTreatyAgree).RowsAffected
}

@ -115,11 +115,14 @@ func Router(router *gin.Engine) {
{
liveC := &live.Live{}
{
liveR.POST("license", liveC.License) // 直播列表
liveR.POST("list", liveC.List) // 直播列表
liveR.POST("info", auth, liveC.Info) // 当前用户直播信息获取
liveR.POST("agree", auth, liveC.Agree) // 同意协议
liveR.POST("follow_list", auth, liveC.FollowList) // 关注主播直播列表
liveR.POST("start", auth, liveC.Start) // 开始直播
liveR.POST("stop", auth, liveC.Stop) // 结束直播
liveR.POST("transcribe", auth, liveC.Transcribe) // 确认录制视频
liveR.POST("live_info", bothAuth, liveC.LiveInfo) // 获取直播间信息
liveR.POST("video_info", bothAuth, liveC.VideoInfo) // 录播信息
liveR.POST("explain", auth, liveC.Explain) // 讲解

@ -1,6 +1,6 @@
#!/usr/bin/env bash
echo "编译中"
go-bindata -o=./app/lib/asset/asset.go -pkg=asset config/...
go-bindata -o=./app/lib/asset/asset.go -pkg=asset config/app.ini config/app.prod.ini config/app.test.ini
# shellcheck disable=SC2006
DIR=`dirname "$0"`

@ -0,0 +1,46 @@
debug=false
[mysql]
dbhost=rm-uf650e6f4439fxw54.mysql.rds.aliyuncs.com
dbport=3306
dbuser=db_recook_super
dbpassword=sduEb9MTSiqhweXGpxa0
dbname=db_recook
prefix=recook_live_
maxIdle=10
maxOpen=500
[tencent]
sdkAppId=1400435566
identifier=admin
expire=600
key=59d502a4e40a8537475cac3fcc4b4c8bfadfb91f832e2923dd4692a4c7cea546
secretId=AKIDf8LHwwQutfAPnvbRpyqGUS9YmjPnqrQn
secretKey=EFp8A5j6oFPJwGJae1Q6VpsdBRQ7gxyh
appId=1303238921
[tencent.live]
pushTreaty=rtmp
pushExpire=86400
pushKey=f670ebf0eccb3ef6c96b6aa7f19e3fa7
pushDomain=livepush.reecook.cn
playTreaty=rtmp
playExpire=86400
playKey=f670ebf0eccb3ef6c96b6aa7f19e3fa7
playDomain=play.reecook.cn
playSuffix=
expireTime=86400
[tencent.live.license]
key=5a4e960bdb3dbf3a3f9c4ea2331ce89c
licenseUrl=http://license.vod2.myqcloud.com/license/v1/fbbf038cfdde5404622cd19030047532/TXLiveSDK.licence
[tencent.short]
expire=600
oneTimeValid=1
key=c3nyGkDcot8aXKcgUZLe
[recook]
url=https://api.reecook.cn/api/v1
private_key=MIIEowIBAAKCAQEAzNWyjYe3qt4YRTDwANxDPNLAJ9TZBuHsSqSjJM5B35fABwN3gwm5Q/SCz/6kgKTqeSgCVPFYhO/zOD6G8K7EJLgx95ZIeAB9EkW+xrhFDDthUZAkA03zHJO6SkFKOciLFVi94BdCdGlNFlnaBBqA+8XvCpD1V8DFc/9cpb5icZvngu8vEkwkbYceCXKUMNxoXY/E2cFe8f2tVFR5pRkQgRLbM70jt4yBGOD8pbuk6fcnD7ghGWgzMq/845N3wISSTp/gAQg8403Fk+8AoL+FKgxUkjUOpPI2XrcpQm0EphuAX4J0Xvo3Hu6TEPZYyqULEXGT2Jukmh0NSkNO0F39xwIDAQABAoIBAQCAqRYPWhkexYQ/Kb8G+1NsiABUxJhRf2UZeZJUEw5DcKEYhq/x6hCpw5LLLOqNN4lj8qKMUlBEqCeAw52k3lGrstsH5ii836mv6YksbyBHz6CQR9anELZM0+nmrF4AL5xVGzmg4VtHncDi8itD+pXcD3bXjzfcF+SuuM6r+QsCykgTc/jw+R6GqOHvD48mUQCI0/Xw6jjAWUUh0jRX2BvLQwcccan5ZCZD3C7M8gGuRFO2vr8lFliQwyFNgwrpE+brLeMNeLHz1S6vMwfqr3r4Mq78wTihoze+3kIs5tdE0YRkJpaPLdeCsvQ8iFfD9nat7wnNHgcQBU+3B+KjOJCZAoGBAOVC8AY8q0UeTFreo44Fgda9Jg+BsR0UwTzTxzozdwSMhIfzb6oDa6tWd8VO0V6FaqK+Urxj6UP3JshAQT8hsq6Hh8tEmUx3rxpQnWZ5bdFJD291apKwTVgDzcf7mo77Ypjpko+Y4Og3weUGOnM+hTdPiToUmkZv78OPgbRR+utdAoGBAOS5c3f7gdfd60mlABPIgpHQccaTyEg3YoCQoB1oXTMk881vzC6w8xwYR0gpKGj6/vG9FeEpgYLi+ydWiNnzH8ZknPiACYZ6g18CzlCUcHUG1PZhKot1zgXQN9/WAvjWZ62Ym4FcPrEaF3+u88Pjj27vQE5MDO8O2uVRQwIGXh9zAoGAGLjGHzYNle91dlsJsffgD2LoJsXqbmNdjwybMCh6jhAE/o/+m4uw4ZH6allcdF/YpuH1FAGGFuEg2nkrT/53QSC2QPINwdQqGqFUx8cSU34YXwF/U4AVZwdJ+mWkPgTXlfuh5UAsCH5ytxqb1O+J9/PorU2pcS0C4sinyOUKNLUCgYBFJNsHVnz2KRxL8xmG4YK3WfBLO7m8OyIIA7Cjsz0ZjP43CKkNJGkaASzrX6XbtqUDp0nJ+6YvTzbluX89hAYDD790UCCRCtBUFKESMw2cEyimItGdv0s87qk1fZkAaLCHBi9cd+pr15tq+hSvD0f5HVKvWMZALpl14Y8EObCSiQKBgCiSKMsn7W5eGVR4cHO5NQ8P6V20ZOGIKvUsJUtlzRtneJERqVXZqVp9MctpLzNluQMGzTR1dEngdnOa2sYgdd8ATYy0NGiZuBDMA3h0f0aVsQublPfUG+0QH/3qryNISWN+m8DnCtkpkUG1GI5/0x9ZVVlSybIvz7H8NltIxXr/
cnd=https://cdn.reecook.cn/static
[live]
maxPraise=3000

@ -29,6 +29,9 @@ playKey=f670ebf0eccb3ef6c96b6aa7f19e3fa7
playDomain=testplay.reecook.cn
playSuffix=
expireTime=86400
[tencent.live.license]
key=5a4e960bdb3dbf3a3f9c4ea2331ce89c
licenseUrl=http://license.vod2.myqcloud.com/license/v1/fbbf038cfdde5404622cd19030047532/TXLiveSDK.licence
[tencent.short]
expire=600
oneTimeValid=1

@ -16,8 +16,10 @@ func main() {
}
r := gin.Default()
// 直播主动拿回调任务
go task.Run()
if !config.Config.Section("").Key("debug").MustBool() {
// 直播主动拿回调任务
go task.Run()
}
// 路由配置
router.Router(r)

Loading…
Cancel
Save