view.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "time"
  7. "go-common/app/interface/main/dm2/model"
  8. account "go-common/app/service/main/account/api"
  9. "go-common/app/service/main/archive/api"
  10. archive "go-common/app/service/main/archive/model/archive"
  11. "go-common/library/log"
  12. "go-common/library/sync/errgroup"
  13. )
  14. // .
  15. var (
  16. _dmFlagFmt = `{"rec_flag":%d,"rec_text":"%s","rec_switch":%d}`
  17. )
  18. // View dm view
  19. func (s *Service) View(c context.Context, mid, aid, oid int64, tp int32, plat int32) (res *model.ViewDm, err error) {
  20. var (
  21. sub *model.Subject
  22. eg errgroup.Group
  23. )
  24. // hot cache
  25. if hit, ok := s.localViewCache[keyLocalView(aid, oid)]; ok {
  26. return hit, nil
  27. }
  28. if sub, err = s.subject(c, model.SubTypeVideo, oid); err != nil {
  29. return
  30. }
  31. res = &model.ViewDm{
  32. Closed: sub.State == model.SubStateClosed,
  33. Flag: json.RawMessage([]byte(fmt.Sprintf(_dmFlagFmt, s.conf.DmFlag.RecFlag, s.conf.DmFlag.RecText, s.conf.DmFlag.RecSwitch))),
  34. }
  35. // mask
  36. eg.Go(func() (err error) {
  37. var (
  38. mask *model.Mask
  39. maskPlat int8
  40. )
  41. switch plat {
  42. case model.PlatWeb:
  43. maskPlat = model.MaskPlatWeb
  44. case model.PlatAndroid, model.PlatIPhone, model.PlatIPad, model.PlatPadHd:
  45. maskPlat = model.MaskPlatMbl
  46. default:
  47. return
  48. }
  49. if mask, err = s.MaskListWithSub(c, oid, maskPlat, sub); err != nil {
  50. log.Error("View.MaskListWithSub(oid:%v) error(%v)", oid, err)
  51. return
  52. }
  53. res.ViewDmMask = mask
  54. return
  55. })
  56. // subtitle
  57. eg.Go(func() (err error) {
  58. var (
  59. subtitle *model.ViewSubtitle
  60. )
  61. if subtitle, err = s.viewSubtitles(c, aid, oid, tp); err != nil {
  62. log.Error("View.viewSubtitles(aid:%v,oid:%v) error(%v)", aid, oid, err)
  63. return
  64. }
  65. res.Subtitle = subtitle
  66. return
  67. })
  68. // special dm
  69. // TODO special dm
  70. // dm seg rule
  71. eg.Go(func() (err error) {
  72. var (
  73. dmSeg *model.ViewDmSeg
  74. )
  75. if dmSeg, err = s.viewDmSeg(c, aid, oid); err != nil {
  76. log.Error("View.viewDmSeg(aid:%v,oid:%v) error(%v)", aid, oid, err)
  77. return
  78. }
  79. res.ViewDmSeg = dmSeg
  80. return
  81. })
  82. // ignore error
  83. eg.Wait()
  84. return
  85. }
  86. func (s *Service) viewSubtitles(c context.Context, aid, oid int64, tp int32) (viewSubtitle *model.ViewSubtitle, err error) {
  87. var (
  88. videoSubtitles []*model.VideoSubtitle
  89. subtitles []*model.ViewVideoSubtitle
  90. reply *account.InfoReply
  91. subtitleSubject *model.SubtitleSubjectReply
  92. )
  93. if videoSubtitles, err = s.getVideoSubtitles(c, oid, tp); err != nil {
  94. log.Error("View.getVideoSubtitles(oid:%v) error(%v)", oid, err)
  95. return
  96. }
  97. for _, videoSubtitle := range videoSubtitles {
  98. subtitle := &model.ViewVideoSubtitle{
  99. ID: videoSubtitle.ID,
  100. Lan: videoSubtitle.Lan,
  101. LanDoc: videoSubtitle.LanDoc,
  102. SubtitleURL: videoSubtitle.SubtitleURL,
  103. }
  104. if videoSubtitle.AuthorMid > 0 {
  105. if reply, _ = s.accountRPC.Info3(c, &account.MidReq{Mid: videoSubtitle.AuthorMid}); reply != nil {
  106. subtitle.Author = &model.ViewAuthor{
  107. Mid: reply.GetInfo().GetMid(),
  108. Name: reply.GetInfo().GetName(),
  109. Sex: reply.GetInfo().GetSex(),
  110. Face: reply.GetInfo().GetFace(),
  111. Sign: reply.GetInfo().GetSign(),
  112. Rank: reply.GetInfo().GetRank(),
  113. }
  114. }
  115. }
  116. subtitles = append(subtitles, subtitle)
  117. }
  118. if subtitleSubject, err = s.SubtitleSubject(c, aid); err != nil {
  119. log.Error("View.subtitleSubject(aid:%v) error(%v)", aid, err)
  120. return
  121. }
  122. viewSubtitle = &model.ViewSubtitle{
  123. Subtitles: subtitles,
  124. }
  125. if subtitleSubject != nil {
  126. viewSubtitle.Lan = subtitleSubject.Lan
  127. viewSubtitle.LanDoc = subtitleSubject.LanDoc
  128. }
  129. return
  130. }
  131. func (s *Service) viewDmSeg(c context.Context, aid, oid int64) (dmSeg *model.ViewDmSeg, err error) {
  132. var (
  133. duration int64
  134. cnt int64
  135. )
  136. if duration, err = s.videoDuration(c, aid, oid); err != nil {
  137. return
  138. }
  139. cnt = duration / model.DefaultPageSize
  140. if duration%model.DefaultPageSize > 0 {
  141. cnt++
  142. }
  143. dmSeg = &model.ViewDmSeg{
  144. PageSize: model.DefaultPageSize,
  145. Total: cnt,
  146. }
  147. return
  148. }
  149. func (s *Service) viewProc() {
  150. if len(s.conf.Localcache.ViewAids) <= 0 {
  151. return
  152. }
  153. ticker := time.NewTicker(time.Duration(s.conf.Localcache.ViewExpire))
  154. defer ticker.Stop()
  155. for range ticker.C {
  156. s.cacheView(s.conf.Localcache.ViewAids)
  157. }
  158. }
  159. func keyLocalView(aid, oid int64) string {
  160. return fmt.Sprintf("dm_view_%d_%d", aid, oid)
  161. }
  162. func (s *Service) cacheView(aids []int64) {
  163. var (
  164. sub *model.Subject
  165. pages []*api.Page
  166. err error
  167. cacheMap = make(map[string]*model.ViewDm)
  168. )
  169. for _, aid := range aids {
  170. pages, err = s.arcRPC.Page3(context.Background(), &archive.ArgAid2{
  171. Aid: aid,
  172. })
  173. if err != nil {
  174. log.Error("localCacheView.Page3(aid:%v) error(%v)", aid, err)
  175. continue
  176. }
  177. for _, page := range pages {
  178. if sub, err = s.subject(context.Background(), model.SubTypeVideo, page.Cid); err != nil {
  179. continue
  180. }
  181. res := &model.ViewDm{
  182. Closed: sub.State == model.SubStateClosed,
  183. Flag: json.RawMessage([]byte(fmt.Sprintf(_dmFlagFmt, s.conf.DmFlag.RecFlag, s.conf.DmFlag.RecText, s.conf.DmFlag.RecSwitch))),
  184. }
  185. // ignore error
  186. if res.Subtitle, err = s.viewSubtitles(context.Background(), aid, page.Cid, model.SubTypeVideo); err != nil {
  187. log.Error("View.viewSubtitles(aid:%v,oid:%v) error(%v)", aid, page.Cid, err)
  188. err = nil
  189. }
  190. if res.ViewDmSeg, err = s.viewDmSeg(context.Background(), aid, page.Cid); err != nil {
  191. log.Error("View.viewDmSeg(aid:%v,oid:%v) error(%v)", aid, page.Cid, err)
  192. err = nil
  193. }
  194. cacheMap[keyLocalView(aid, page.Cid)] = res
  195. }
  196. }
  197. s.localViewCache = cacheMap
  198. }