uniapp,h5

lottoryDetail0.vue 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. <template>
  2. <view class="container">
  3. <view class="search-container">
  4. <uni-search-bar class="uni-mt-10" radius="5" placeholder="搜索视频名称" clearButton="auto" cancelButton="none"
  5. @confirm="search">
  6. </uni-search-bar>
  7. </view>
  8. <view class="uni-list uni-common-mt">
  9. <view class="video-container">
  10. <video id="myVideo" :src="videoSrc" :poster="posterSrc" @error="videoErrorCallback"
  11. :danmu-list="danmuList" controls show-loading show-mute-btn></video>
  12. </view>
  13. <!-- #ifndef MP-ALIPAY -->
  14. <!-- <view class="uni-list uni-common-mt">
  15. <view class="uni-list-cell">
  16. <view>
  17. <view class="uni-label">弹幕内容</view>
  18. </view>
  19. <view class="uni-list-cell-db">
  20. <input v-model="danmuValue" class="uni-input" type="text" placeholder="在此处输入弹幕内容" />
  21. </view>
  22. </view>
  23. </view> -->
  24. <!-- <view class="uni-btn-v">
  25. <button @click="sendDanmu" class="page-body-button">发送弹幕</button>
  26. </view> -->
  27. <!-- #endif -->
  28. <uni-section title="播放列表" type="line">
  29. <uni-list v-for="(v, k) in videoList" :key="k">
  30. <uni-list-item clickable @click="onPlayListClick(v)">
  31. <template v-slot:header>
  32. <view class="slot-box">
  33. <image class="slot-image" :src="v.imSrc"></image>
  34. </view>
  35. </template>
  36. <template v-slot:body>
  37. <text class="slot-box slot-text">{{v.title}}</text>
  38. <!-- <text class="slot-box slot-text"></text> -->
  39. </template>
  40. <template v-slot:footer>
  41. <text class="slot-box slot-text-play">立即载入</text>
  42. </template>
  43. </uni-list-item>
  44. </uni-list>
  45. </uni-section>
  46. </view>
  47. </view>
  48. </template>
  49. <script>
  50. export default {
  51. data() {
  52. return {
  53. src: '',
  54. danmuList: [{
  55. text: '第 1s 出现的弹幕',
  56. color: '#ff0000',
  57. time: 1
  58. }],
  59. videoList: [{
  60. title: '鞠婧祎视频 1 ',
  61. viSrc: 'https://afanai.top:8088/video/982789760.mp4',
  62. imSrc: 'https://afanai.top:8088/video/982789760frame.jpg',
  63. video_id: ''
  64. },
  65. {
  66. title: '鞠婧祎视频 2 ',
  67. viSrc: 'https://afanai.top:8088/video/428743782.mp4',
  68. imSrc: 'https://afanai.top:8088/video/428743782frame.jpg',
  69. video_id: ''
  70. }
  71. ],
  72. videoListDefault: [{
  73. title: '鞠婧祎视频 1 ',
  74. viSrc: 'https://afanai.top:8088/video/982789760.mp4',
  75. imSrc: 'https://afanai.top:8088/video/982789760frame.jpg',
  76. video_id: ''
  77. },
  78. {
  79. title: '鞠婧祎视频 2 ',
  80. viSrc: 'https://afanai.top:8088/video/428743782.mp4',
  81. imSrc: 'https://afanai.top:8088/video/428743782frame.jpg',
  82. video_id: ''
  83. }
  84. ],
  85. danmuValue: '',
  86. videoSrc: '',
  87. posterSrc: ''
  88. }
  89. },
  90. onReady: function(res) {
  91. // #ifndef MP-ALIPAY
  92. this.videoContext = uni.createVideoContext('myVideo')
  93. // #endif
  94. },
  95. methods: {
  96. sendDanmu: function() {
  97. this.videoContext.sendDanmu({
  98. text: this.danmuValue,
  99. color: this.getRandomColor()
  100. });
  101. this.danmuValue = '';
  102. },
  103. videoErrorCallback: function(e) {
  104. // uni.showModal({
  105. // content: e.target.errMsg,
  106. // showCancel: false
  107. // })
  108. },
  109. getRandomColor: function() {
  110. const rgb = []
  111. for (let i = 0; i < 3; ++i) {
  112. let color = Math.floor(Math.random() * 256).toString(16)
  113. color = color.length == 1 ? '0' + color : color
  114. rgb.push(color)
  115. }
  116. return '#' + rgb.join('')
  117. },
  118. async search(res) {
  119. if (res.value == "") {
  120. this.videoList = this.videoListDefault;
  121. } else {
  122. let newVideoList = [];
  123. this.videoList = [];
  124. newVideoList = await this.fetchSearchResults(res.value);
  125. newVideoList.forEach((v, index) => {
  126. let videoItem = {
  127. title: v["video_name"],
  128. // viSrc: v["video_url"],
  129. viSrc: "",
  130. imSrc: v["cover_url"],
  131. video_id: v["video_id"]
  132. };
  133. this.videoList.push(videoItem);
  134. })
  135. }
  136. this.videoSrc = "";
  137. this.posterSrc = "";
  138. },
  139. async fetchSearchResults(query) {
  140. // 调用后端接口
  141. // 直接在URL后拼接查询参数
  142. const res = await uni.request({
  143. url: `https://afanai.top:8089/v1/video/search?query=${encodeURIComponent(query)}`,
  144. method: 'GET',
  145. header: {} // GET请求不需要content-type
  146. });
  147. if (res.statusCode === 200) {
  148. const data = res.data;
  149. // 检查数据是否为JSON格式
  150. if (typeof data === 'string') {
  151. data = JSON.parse(data);
  152. }
  153. // 假设后端返回的是一个名为'queryRes'的数组
  154. if (Array.isArray(data.queryRes)) {
  155. // 处理列表数据,例如更新组件数据
  156. return data.queryRes;
  157. } else {
  158. uni.showToast({
  159. title: '未搜索到相关视频',
  160. duration: 2000,
  161. icon: 'none'
  162. });
  163. return [];
  164. }
  165. } else {
  166. uni.showToast({
  167. title: '查找失败',
  168. duration: 2000,
  169. icon: 'none'
  170. });
  171. return [];
  172. }
  173. },
  174. // search: function(res) {
  175. // // 更新搜索列表
  176. // uni.showToast({
  177. // title: res.value,
  178. // icon: 'none'
  179. // })
  180. // },
  181. async onPlayListClick(res) {
  182. if (this.posterSrc == res.imSrc) {
  183. uni.showToast({
  184. title: "已载入",
  185. icon: 'success'
  186. })
  187. return;
  188. }
  189. if (res.video_id === '') {
  190. this.videoSrc = res.viSrc;
  191. this.posterSrc = res.imSrc;
  192. uni.showToast({
  193. title: res.title,
  194. icon: 'success'
  195. })
  196. } else {
  197. // 查询链接
  198. this.videoSrc = await this.fetchVideoUrl(res.video_id);
  199. this.posterSrc = res.imSrc;
  200. uni.showToast({
  201. title: res.title,
  202. icon: 'success'
  203. })
  204. }
  205. },
  206. async fetchVideoUrl(query) {
  207. // 调用后端接口
  208. // 直接在URL后拼接查询参数
  209. const res = await uni.request({
  210. url: `https://afanai.top:8089/v1/video/getBlobUrl?query=${encodeURIComponent(query)}`,
  211. method: 'GET',
  212. header: {} // GET请求不需要content-type
  213. });
  214. if (res.statusCode === 200) {
  215. const data = res.data;
  216. // 检查数据是否为JSON格式
  217. if (typeof data === 'string') {
  218. data = JSON.parse(data);
  219. }
  220. // 假设后端返回的是一个名为'queryRes'
  221. if (data.queryRes) {
  222. // 处理列表数据,例如更新组件数据
  223. return data.queryRes;
  224. } else {
  225. uni.showToast({
  226. title: '未搜索到相关视频',
  227. duration: 2000,
  228. icon: 'none'
  229. });
  230. return "";
  231. }
  232. } else {
  233. uni.showToast({
  234. title: '查找失败',
  235. duration: 2000,
  236. icon: 'none'
  237. });
  238. return "";
  239. }
  240. },
  241. }
  242. }
  243. </script>
  244. <style scoped>
  245. .video-container {
  246. display: flex;
  247. justify-content: center;
  248. align-items: center;
  249. }
  250. .video {
  251. width: 300px;
  252. height: 225px;
  253. line-height: 0;
  254. overflow: hidden;
  255. position: relative;
  256. }
  257. .slot-box {
  258. /* #ifndef APP-NVUE */
  259. display: flex;
  260. /* #endif */
  261. flex-direction: row;
  262. align-items: center;
  263. }
  264. .slot-image {
  265. /* #ifndef APP-NVUE */
  266. display: block;
  267. /* #endif */
  268. margin-right: 10px;
  269. width: 72px;
  270. height: 48px;
  271. }
  272. .slot-text {
  273. flex: 1;
  274. font-size: 16px;
  275. margin-right: 10px;
  276. }
  277. .slot-text-play {
  278. font-size: 14px;
  279. color: #008acf;
  280. margin-right: 5px;
  281. }
  282. </style>