123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- package watermark
- import (
- "bufio"
- "context"
- "crypto/md5"
- "encoding/json"
- "fmt"
- "io"
- "os"
- "strconv"
- "time"
- "go-common/app/interface/main/creative/model/newcomer"
- "go-common/app/interface/main/creative/model/watermark"
- "go-common/app/service/main/account/model"
- "go-common/library/ecode"
- "go-common/library/log"
- "go-common/library/net/metadata"
- )
- var (
- wmTipFormat = "原创水印将展示在视频%s角,以防他人盗用"
- wmTipMap = map[int]string{
- 1: "左上",
- 2: "右上", // default
- 3: "左下",
- 4: "右下",
- }
- )
- // WaterMark get user watermark.
- func (s *Service) WaterMark(c context.Context, mid int64) (w *watermark.Watermark, err error) {
- if w, err = s.wm.WaterMark(c, mid); err != nil {
- log.Error("s.wm.WaterMark(%d) error(%v)", mid, err)
- return
- }
- if w == nil {
- w = &watermark.Watermark{
- MID: mid,
- Pos: 2,
- Ty: 1,
- }
- }
- w.Tip = fmt.Sprintf(wmTipFormat, wmTipMap[int(w.Pos)])
- var pf *model.Profile
- ip := metadata.String(c, metadata.RemoteIP)
- if pf, err = s.acc.Profile(c, mid, ip); err != nil {
- log.Error("s.acc.Profile(%d) error(%v)", mid, err)
- return
- }
- if pf == nil {
- return
- }
- w.Uname = pf.Name
- return
- }
- // WaterMarkSet set watermark for user.
- func (s *Service) WaterMarkSet(c context.Context, wp *watermark.WatermarkParam) (wm *watermark.Watermark, err error) {
- var (
- w *watermark.Watermark
- wmm *watermark.Watermark
- pf *model.Profile
- )
- mid, st, ty, pos, sync, ip := wp.MID, wp.State, wp.Ty, wp.Pos, wp.Sync, wp.IP
- if !watermark.IsState(st) {
- err = ecode.CreativeWaterMarkWrongState
- return
- }
- if !watermark.IsType(ty) {
- err = ecode.CreativeWaterMarkWrongType
- return
- }
- if !watermark.IsPos(pos) {
- err = ecode.CreativeWaterMarkWrongPosition // 位置参数错误
- return
- }
- if w, err = s.wm.WaterMark(c, mid); err != nil {
- log.Error("s.wm.Watermark(%d) error(%v)", mid, err)
- return
- }
- wm = &watermark.Watermark{
- MID: mid,
- State: st,
- Ty: ty,
- Pos: pos,
- MTime: time.Now(),
- }
- if w != nil {
- wm.ID = w.ID
- wm.Uname = w.Uname
- wm.URL = w.URL
- wm.MD5 = w.MD5
- wm.Info = w.Info
- wm.CTime = w.CTime
- }
- if st == watermark.StatOpen || st == watermark.StatPreview { //开启、预览
- var (
- text string
- isName bool
- )
- if ty == watermark.TypeName || ty == watermark.TypeNewName { //增加用户名在logo下方的水印
- if pf, err = s.acc.Profile(c, mid, ip); err != nil {
- log.Error("s.acc.Profile(%d) error(%v)", mid, err)
- return
- }
- if pf == nil {
- return
- }
- if w != nil && w.State == watermark.StatOpen && ty == w.Ty && pos == w.Pos && w.Uname == pf.Name && sync == 0 {
- log.Info("repeat uname watermark")
- return
- }
- text = pf.Name
- wm.Uname = text
- isName = true
- } else if ty == watermark.TypeUID {
- if w != nil && w.State == watermark.StatOpen && ty == w.Ty && pos == w.Pos {
- log.Info("repeat uid watermark")
- return
- }
- text = strconv.FormatInt(mid, 10)
- isName = false
- }
- if ty == watermark.TypeName || ty == watermark.TypeUID { //old get wm
- if wmm, err = s.draw(c, mid, text, isName); err != nil {
- log.Error("s.draw error(%v)", err)
- err = ecode.CreativeWaterMarkCreateFailed
- return
- }
- if wmm == nil {
- return
- }
- wm.Info, wm.URL, wm.MD5 = wmm.Info, wmm.URL, wmm.MD5
- } else if ty == watermark.TypeNewName { //new get wm
- var gm *watermark.Watermark
- gm, err = s.GenWm(c, mid, wm.Uname, ip)
- if err != nil || gm == nil {
- return
- }
- wm.Info, wm.URL, wm.MD5 = gm.Info, gm.URL, gm.MD5
- }
- }
- if st == watermark.StatPreview { //预览不更新db
- return
- }
- if w == nil {
- wm.CTime = time.Now()
- _, err = s.wm.AddWaterMark(c, wm)
- } else {
- _, err = s.wm.UpWaterMark(c, wm)
- }
- res, _ := s.WaterMark(c, mid)
- if res != nil && res.State == 1 && res.URL != "" {
- s.p.TaskPub(mid, newcomer.MsgForWaterMark, newcomer.MsgFinishedCount)
- }
- return
- }
- func (s *Service) userInfoConsumer() {
- defer s.wg.Done()
- var (
- msgs = s.userInfoSub.Messages()
- err error
- c = context.TODO()
- )
- for {
- msg, ok := <-msgs
- if !ok {
- log.Error("s.userInfoSub.Messages closed")
- return
- }
- msg.Commit()
- s.userInfoMo++
- u := &watermark.Msg{}
- if err = json.Unmarshal(msg.Value, u); err != nil {
- log.Error("json.Unmarshal(%v) error(%v)", string(msg.Value), err)
- continue
- }
- if u == nil || u.Action != "update" {
- continue
- }
- s.update(c, u)
- log.Info("userInfoConsumer key(%s) value(%s) partition(%d) offset(%d) commit", msg.Key, msg.Value, msg.Partition, msg.Offset)
- }
- }
- func (s *Service) update(c context.Context, u *watermark.Msg) (err error) {
- if u.Old.Uname == u.New.Uname {
- return
- }
- var w, wm *watermark.Watermark
- if w, err = s.wm.WaterMark(c, u.New.MID); err != nil {
- log.Error("s.wm.Watermark(%d) error(%v)", u.New.MID, err)
- return
- }
- if w == nil {
- return
- }
- log.Info("user mid(%d) origin data(%+v)", w.MID, w)
- uname := u.New.Uname
- if w.Ty == watermark.TypeName {
- wm, err = s.draw(c, w.MID, uname, true)
- if err != nil {
- log.Error("s.draw error(%v)", err)
- err = ecode.CreativeWaterMarkCreateFailed
- return
- }
- if wm == nil {
- return
- }
- if wm.MD5 == "" {
- log.Error("md5Sum fail")
- err = ecode.CreativeWaterMarkCreateFailed
- return
- }
- w.Info, w.URL, w.MD5 = wm.Info, wm.URL, wm.MD5
- } else if w.Ty == watermark.TypeNewName { //new get wm
- var gm *watermark.Watermark
- gm, err = s.GenWm(c, w.MID, uname, "")
- if err != nil || gm == nil {
- return
- }
- w.Info, w.URL, w.MD5 = gm.Info, gm.URL, gm.MD5
- }
- w.Uname = uname
- w.MTime = time.Now()
- _, err = s.wm.UpWaterMark(c, w)
- log.Info("user mid(%d) uname from (%s) to (%s) update data(%+v)", u.New.MID, u.Old.Uname, u.New.Uname, w)
- return
- }
- func (s *Service) draw(c context.Context, mid int64, text string, isUname bool) (w *watermark.Watermark, err error) {
- dw, err := s.drawimg.Make(c, mid, text, isUname)
- if err != nil {
- log.Error("s.drawimg.Make error(%v)", err)
- return
- }
- if dw == nil {
- return
- }
- file := dw.File
- defer os.Remove(file)
- url, err := s.bfs.UploadByFile(c, file)
- if err != nil {
- log.Error("s.bfs.UploadByFile error(%v)", err)
- return
- }
- info, err := ImageInfo(dw.CanvasWidth, dw.CanvasHeight)
- if err != nil {
- return
- }
- w = &watermark.Watermark{}
- w.URL, w.Info, w.MD5 = url, info, MD5Sum(file)
- return
- }
- // MD5Sum calculate file md5.
- func MD5Sum(file string) string {
- f, err := os.Open(file)
- if err != nil {
- log.Error("md5Sum os.Open error(%v)", err)
- return ""
- }
- defer f.Close()
- r := bufio.NewReader(f)
- h := md5.New()
- _, err = io.Copy(h, r)
- if err != nil {
- log.Error("md5Sum io.Copy error(%v)", err)
- return ""
- }
- return fmt.Sprintf("%x", h.Sum(nil))
- }
- //GenWm for new genwm api.
- func (s *Service) GenWm(c context.Context, mid int64, uname, ip string) (wm *watermark.Watermark, err error) {
- var genwm *watermark.GenWatermark
- genwm, err = s.wm.GenWm(c, mid, uname, ip)
- if err != nil {
- log.Error("s.wm.GenWm error(%v)", err)
- return
- }
- if genwm == nil {
- return
- }
- wm = &watermark.Watermark{}
- info, err := ImageInfo(genwm.Width, genwm.Height)
- if err != nil {
- return
- }
- wm.URL, wm.MD5, wm.Info = genwm.Location, genwm.MD5, info
- return
- }
- //ImageInfo for image info json.
- func ImageInfo(width, height int) (info string, err error) {
- imgInfo := &watermark.Image{
- Width: width,
- Height: height,
- }
- var bs []byte
- if bs, err = json.Marshal(&imgInfo); err != nil {
- log.Error("json.Marshal error(%v)", err)
- return
- }
- info = string(bs)
- return
- }
- // AsyncWaterMarkSet fn
- func (s *Service) AsyncWaterMarkSet(wp *watermark.WatermarkParam) {
- if s.closed {
- log.Warn("AsyncWaterMarkSet chan is closed")
- return
- }
- select {
- case s.wmChan <- wp:
- default:
- log.Error("AsyncWaterMarkSet chan is full data(%+v)", wp)
- }
- }
- func (s *Service) asyncWmSetProc() {
- c := context.Background()
- for {
- v, ok := <-s.wmChan
- if ok {
- log.Info("watermark set by async with data(%+v)", v)
- if _, err := s.WaterMarkSet(c, v); err != nil {
- log.Error("s.WaterMarkSet watermark err (%+v)", err)
- }
- }
- }
- }
|