watermark.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. package watermark
  2. import (
  3. "bufio"
  4. "context"
  5. "crypto/md5"
  6. "encoding/json"
  7. "fmt"
  8. "io"
  9. "os"
  10. "strconv"
  11. "time"
  12. "go-common/app/interface/main/creative/model/newcomer"
  13. "go-common/app/interface/main/creative/model/watermark"
  14. "go-common/app/service/main/account/model"
  15. "go-common/library/ecode"
  16. "go-common/library/log"
  17. "go-common/library/net/metadata"
  18. )
  19. var (
  20. wmTipFormat = "原创水印将展示在视频%s角,以防他人盗用"
  21. wmTipMap = map[int]string{
  22. 1: "左上",
  23. 2: "右上", // default
  24. 3: "左下",
  25. 4: "右下",
  26. }
  27. )
  28. // WaterMark get user watermark.
  29. func (s *Service) WaterMark(c context.Context, mid int64) (w *watermark.Watermark, err error) {
  30. if w, err = s.wm.WaterMark(c, mid); err != nil {
  31. log.Error("s.wm.WaterMark(%d) error(%v)", mid, err)
  32. return
  33. }
  34. if w == nil {
  35. w = &watermark.Watermark{
  36. MID: mid,
  37. Pos: 2,
  38. Ty: 1,
  39. }
  40. }
  41. w.Tip = fmt.Sprintf(wmTipFormat, wmTipMap[int(w.Pos)])
  42. var pf *model.Profile
  43. ip := metadata.String(c, metadata.RemoteIP)
  44. if pf, err = s.acc.Profile(c, mid, ip); err != nil {
  45. log.Error("s.acc.Profile(%d) error(%v)", mid, err)
  46. return
  47. }
  48. if pf == nil {
  49. return
  50. }
  51. w.Uname = pf.Name
  52. return
  53. }
  54. // WaterMarkSet set watermark for user.
  55. func (s *Service) WaterMarkSet(c context.Context, wp *watermark.WatermarkParam) (wm *watermark.Watermark, err error) {
  56. var (
  57. w *watermark.Watermark
  58. wmm *watermark.Watermark
  59. pf *model.Profile
  60. )
  61. mid, st, ty, pos, sync, ip := wp.MID, wp.State, wp.Ty, wp.Pos, wp.Sync, wp.IP
  62. if !watermark.IsState(st) {
  63. err = ecode.CreativeWaterMarkWrongState
  64. return
  65. }
  66. if !watermark.IsType(ty) {
  67. err = ecode.CreativeWaterMarkWrongType
  68. return
  69. }
  70. if !watermark.IsPos(pos) {
  71. err = ecode.CreativeWaterMarkWrongPosition // 位置参数错误
  72. return
  73. }
  74. if w, err = s.wm.WaterMark(c, mid); err != nil {
  75. log.Error("s.wm.Watermark(%d) error(%v)", mid, err)
  76. return
  77. }
  78. wm = &watermark.Watermark{
  79. MID: mid,
  80. State: st,
  81. Ty: ty,
  82. Pos: pos,
  83. MTime: time.Now(),
  84. }
  85. if w != nil {
  86. wm.ID = w.ID
  87. wm.Uname = w.Uname
  88. wm.URL = w.URL
  89. wm.MD5 = w.MD5
  90. wm.Info = w.Info
  91. wm.CTime = w.CTime
  92. }
  93. if st == watermark.StatOpen || st == watermark.StatPreview { //开启、预览
  94. var (
  95. text string
  96. isName bool
  97. )
  98. if ty == watermark.TypeName || ty == watermark.TypeNewName { //增加用户名在logo下方的水印
  99. if pf, err = s.acc.Profile(c, mid, ip); err != nil {
  100. log.Error("s.acc.Profile(%d) error(%v)", mid, err)
  101. return
  102. }
  103. if pf == nil {
  104. return
  105. }
  106. if w != nil && w.State == watermark.StatOpen && ty == w.Ty && pos == w.Pos && w.Uname == pf.Name && sync == 0 {
  107. log.Info("repeat uname watermark")
  108. return
  109. }
  110. text = pf.Name
  111. wm.Uname = text
  112. isName = true
  113. } else if ty == watermark.TypeUID {
  114. if w != nil && w.State == watermark.StatOpen && ty == w.Ty && pos == w.Pos {
  115. log.Info("repeat uid watermark")
  116. return
  117. }
  118. text = strconv.FormatInt(mid, 10)
  119. isName = false
  120. }
  121. if ty == watermark.TypeName || ty == watermark.TypeUID { //old get wm
  122. if wmm, err = s.draw(c, mid, text, isName); err != nil {
  123. log.Error("s.draw error(%v)", err)
  124. err = ecode.CreativeWaterMarkCreateFailed
  125. return
  126. }
  127. if wmm == nil {
  128. return
  129. }
  130. wm.Info, wm.URL, wm.MD5 = wmm.Info, wmm.URL, wmm.MD5
  131. } else if ty == watermark.TypeNewName { //new get wm
  132. var gm *watermark.Watermark
  133. gm, err = s.GenWm(c, mid, wm.Uname, ip)
  134. if err != nil || gm == nil {
  135. return
  136. }
  137. wm.Info, wm.URL, wm.MD5 = gm.Info, gm.URL, gm.MD5
  138. }
  139. }
  140. if st == watermark.StatPreview { //预览不更新db
  141. return
  142. }
  143. if w == nil {
  144. wm.CTime = time.Now()
  145. _, err = s.wm.AddWaterMark(c, wm)
  146. } else {
  147. _, err = s.wm.UpWaterMark(c, wm)
  148. }
  149. res, _ := s.WaterMark(c, mid)
  150. if res != nil && res.State == 1 && res.URL != "" {
  151. s.p.TaskPub(mid, newcomer.MsgForWaterMark, newcomer.MsgFinishedCount)
  152. }
  153. return
  154. }
  155. func (s *Service) userInfoConsumer() {
  156. defer s.wg.Done()
  157. var (
  158. msgs = s.userInfoSub.Messages()
  159. err error
  160. c = context.TODO()
  161. )
  162. for {
  163. msg, ok := <-msgs
  164. if !ok {
  165. log.Error("s.userInfoSub.Messages closed")
  166. return
  167. }
  168. msg.Commit()
  169. s.userInfoMo++
  170. u := &watermark.Msg{}
  171. if err = json.Unmarshal(msg.Value, u); err != nil {
  172. log.Error("json.Unmarshal(%v) error(%v)", string(msg.Value), err)
  173. continue
  174. }
  175. if u == nil || u.Action != "update" {
  176. continue
  177. }
  178. s.update(c, u)
  179. log.Info("userInfoConsumer key(%s) value(%s) partition(%d) offset(%d) commit", msg.Key, msg.Value, msg.Partition, msg.Offset)
  180. }
  181. }
  182. func (s *Service) update(c context.Context, u *watermark.Msg) (err error) {
  183. if u.Old.Uname == u.New.Uname {
  184. return
  185. }
  186. var w, wm *watermark.Watermark
  187. if w, err = s.wm.WaterMark(c, u.New.MID); err != nil {
  188. log.Error("s.wm.Watermark(%d) error(%v)", u.New.MID, err)
  189. return
  190. }
  191. if w == nil {
  192. return
  193. }
  194. log.Info("user mid(%d) origin data(%+v)", w.MID, w)
  195. uname := u.New.Uname
  196. if w.Ty == watermark.TypeName {
  197. wm, err = s.draw(c, w.MID, uname, true)
  198. if err != nil {
  199. log.Error("s.draw error(%v)", err)
  200. err = ecode.CreativeWaterMarkCreateFailed
  201. return
  202. }
  203. if wm == nil {
  204. return
  205. }
  206. if wm.MD5 == "" {
  207. log.Error("md5Sum fail")
  208. err = ecode.CreativeWaterMarkCreateFailed
  209. return
  210. }
  211. w.Info, w.URL, w.MD5 = wm.Info, wm.URL, wm.MD5
  212. } else if w.Ty == watermark.TypeNewName { //new get wm
  213. var gm *watermark.Watermark
  214. gm, err = s.GenWm(c, w.MID, uname, "")
  215. if err != nil || gm == nil {
  216. return
  217. }
  218. w.Info, w.URL, w.MD5 = gm.Info, gm.URL, gm.MD5
  219. }
  220. w.Uname = uname
  221. w.MTime = time.Now()
  222. _, err = s.wm.UpWaterMark(c, w)
  223. log.Info("user mid(%d) uname from (%s) to (%s) update data(%+v)", u.New.MID, u.Old.Uname, u.New.Uname, w)
  224. return
  225. }
  226. func (s *Service) draw(c context.Context, mid int64, text string, isUname bool) (w *watermark.Watermark, err error) {
  227. dw, err := s.drawimg.Make(c, mid, text, isUname)
  228. if err != nil {
  229. log.Error("s.drawimg.Make error(%v)", err)
  230. return
  231. }
  232. if dw == nil {
  233. return
  234. }
  235. file := dw.File
  236. defer os.Remove(file)
  237. url, err := s.bfs.UploadByFile(c, file)
  238. if err != nil {
  239. log.Error("s.bfs.UploadByFile error(%v)", err)
  240. return
  241. }
  242. info, err := ImageInfo(dw.CanvasWidth, dw.CanvasHeight)
  243. if err != nil {
  244. return
  245. }
  246. w = &watermark.Watermark{}
  247. w.URL, w.Info, w.MD5 = url, info, MD5Sum(file)
  248. return
  249. }
  250. // MD5Sum calculate file md5.
  251. func MD5Sum(file string) string {
  252. f, err := os.Open(file)
  253. if err != nil {
  254. log.Error("md5Sum os.Open error(%v)", err)
  255. return ""
  256. }
  257. defer f.Close()
  258. r := bufio.NewReader(f)
  259. h := md5.New()
  260. _, err = io.Copy(h, r)
  261. if err != nil {
  262. log.Error("md5Sum io.Copy error(%v)", err)
  263. return ""
  264. }
  265. return fmt.Sprintf("%x", h.Sum(nil))
  266. }
  267. //GenWm for new genwm api.
  268. func (s *Service) GenWm(c context.Context, mid int64, uname, ip string) (wm *watermark.Watermark, err error) {
  269. var genwm *watermark.GenWatermark
  270. genwm, err = s.wm.GenWm(c, mid, uname, ip)
  271. if err != nil {
  272. log.Error("s.wm.GenWm error(%v)", err)
  273. return
  274. }
  275. if genwm == nil {
  276. return
  277. }
  278. wm = &watermark.Watermark{}
  279. info, err := ImageInfo(genwm.Width, genwm.Height)
  280. if err != nil {
  281. return
  282. }
  283. wm.URL, wm.MD5, wm.Info = genwm.Location, genwm.MD5, info
  284. return
  285. }
  286. //ImageInfo for image info json.
  287. func ImageInfo(width, height int) (info string, err error) {
  288. imgInfo := &watermark.Image{
  289. Width: width,
  290. Height: height,
  291. }
  292. var bs []byte
  293. if bs, err = json.Marshal(&imgInfo); err != nil {
  294. log.Error("json.Marshal error(%v)", err)
  295. return
  296. }
  297. info = string(bs)
  298. return
  299. }
  300. // AsyncWaterMarkSet fn
  301. func (s *Service) AsyncWaterMarkSet(wp *watermark.WatermarkParam) {
  302. if s.closed {
  303. log.Warn("AsyncWaterMarkSet chan is closed")
  304. return
  305. }
  306. select {
  307. case s.wmChan <- wp:
  308. default:
  309. log.Error("AsyncWaterMarkSet chan is full data(%+v)", wp)
  310. }
  311. }
  312. func (s *Service) asyncWmSetProc() {
  313. c := context.Background()
  314. for {
  315. v, ok := <-s.wmChan
  316. if ok {
  317. log.Info("watermark set by async with data(%+v)", v)
  318. if _, err := s.WaterMarkSet(c, v); err != nil {
  319. log.Error("s.WaterMarkSet watermark err (%+v)", err)
  320. }
  321. }
  322. }
  323. }