fuyu-MixSwiper.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <swiper class="swiper" circular :autoplay="autoplaySwiper" :current="swiperCurrent" @change="swiperChange">
  3. <swiper-item v-for="(item,index) in list" :key="index">
  4. <image class="swiper-image" v-if="isImageUrl(item.url)" :src="item.url" mode="scaleToFill" lazy-load />
  5. <div style="height: 100%;width: 100%;position: relative;" v-else>
  6. <!-- #ifdef APP -->
  7. <MyVideo :item="item" :isPlay="!isShow && videoId == item.id" @onEnded="endVideo(item.id)" />
  8. <view v-if="isShow"
  9. style="z-index:99;position: absolute;width:100%;height:100%;top:0;left:0;display:flex; justify-content:center; align-items:center;">
  10. <image @click.stop="plays(item.id,index)" src="@/static/bofang.png"
  11. style="width: 40px;height: 40px;"></image>
  12. </view>
  13. <!-- #endif -->
  14. <!-- #ifdef MP-WEIXIN -->
  15. <video class="swiper-video" :id="`Video${item.id}`" :src="item.url" :autoplay="true"
  16. :controls="false" :show-center-play-btn="false" :enable-progress-gesture="false"
  17. @ended="endVideo(item.id)" @loadedmetadata="loadVideo(item.id)" />
  18. <cover-view v-if="isShow"
  19. style="z-index:99;position: absolute;width:100%;height:100%;top:0;left:0;display:flex; justify-content:center; align-items:center;">
  20. <cover-image @click.stop="plays(item.id,index)" src="@/static/bofang.png"
  21. style="width: 40px;height: 40px;"></cover-image>
  22. </cover-view>
  23. <!-- #endif -->
  24. <!-- #ifdef H5 -->
  25. <video class="swiper-video" :id="`Video${item.id}`" :src="item.url" :autoplay="true" :controls="false"
  26. :show-center-play-btn="false" :enable-progress-gesture="false" @ended="endVideo(item.id)" />
  27. <view v-if="isShow"
  28. style="z-index:99;position: absolute;width:100%;height:100%;top:0;left:0;display:flex; justify-content:center; align-items:center;">
  29. <image @click.stop="plays(item.id,index)" src="@/static/bofang.png"
  30. style="width: 40px;height: 40px;"></image>
  31. </view>
  32. <!-- #endif -->
  33. </div>
  34. </swiper-item>
  35. </swiper>
  36. </template>
  37. <script>
  38. // #ifdef APP
  39. import MyVideo from '@/components/fuyu-MixSwiper/MyVideo.vue'
  40. // #endif
  41. export default {
  42. components: {
  43. // #ifdef APP
  44. MyVideo
  45. // #endif
  46. },
  47. props: {
  48. list: {
  49. type: Array,
  50. default: () => []
  51. }
  52. },
  53. data() {
  54. return {
  55. swiperCurrent: 0, //轮播下标
  56. autoplaySwiper: true,
  57. isShow: true,
  58. videoIndex: null,
  59. videoId: null,
  60. }
  61. },
  62. created() {
  63. // #ifdef MP-WEIXIN
  64. const regex = /^(http|https):\/\//;
  65. this.list.forEach(v => {
  66. const bool = regex.test(v.url);
  67. if (!bool) {
  68. const fs = uni.getFileSystemManager();
  69. const res = new Promise((resolve, reject) => {
  70. fs.readFile({
  71. filePath: v.url, // 相对于static目录的路径
  72. encoding: 'base64',
  73. success: (res) => {
  74. v.url = res.data
  75. // 为临时文件生成一个文件名,您可以根据需要自定义文件名
  76. const fileName = `temp_video_${Date.now()}.mp4`;
  77. // 指定临时文件的完整路径
  78. const tempFilePath = `${uni.env.USER_DATA_PATH}/${fileName}`;
  79. // 将Base64编码的数据写入临时文件
  80. fs.writeFile({
  81. filePath: tempFilePath, // 临时文件路径
  82. data: v.url, // Base64数据(去掉数据URI部分)
  83. encoding: 'base64', // 指定编码格式为base64
  84. success: () => {
  85. v.url = tempFilePath
  86. },
  87. fail: (err) => {
  88. console.error('写入文件失败:', err);
  89. }
  90. });
  91. },
  92. fail: (err) => {
  93. console.error('读取视频文件失败:', err);
  94. }
  95. });
  96. });
  97. }
  98. })
  99. // #endif
  100. },
  101. methods: {
  102. swiperChange(e) {
  103. this.swiperCurrent = e.detail.current;
  104. if (e.detail.current != this.videoIndex) {
  105. this.endVideo(this.videoId, 'swiper')
  106. }
  107. },
  108. isImageUrl(url) {
  109. // 定义常见的图片文件后缀
  110. const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'tiff', 'svg'];
  111. // 获取URL中的文件后缀
  112. const ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase();
  113. // 检查文件后缀是否在图片文件后缀数组中
  114. return imageExtensions.includes(ext)
  115. },
  116. //当video播放得时候 覆盖曾隐藏,不能轮播
  117. plays(id, index) {
  118. // #ifndef APP
  119. let videoContext = uni.createVideoContext(`Video${id}`, this);
  120. videoContext.play()
  121. // #endif
  122. this.videoId = id
  123. this.videoIndex = index
  124. this.isShow = false
  125. this.autoplaySwiper = false
  126. },
  127. //加载视频时触发,解决小程序加载报错问题
  128. loadVideo(id) {
  129. let videoContext = uni.createVideoContext(`Video${id}`, this);
  130. videoContext.pause()
  131. videoContext.seek(0)
  132. },
  133. //当video播放结束得时候 进行初始化,恢复轮播
  134. endVideo(id, type) {
  135. // #ifndef APP
  136. let videoContext = uni.createVideoContext(`Video${id}`, this);
  137. videoContext.pause()
  138. // #endif
  139. this.isShow = true
  140. this.videoIndex = null
  141. this.videoId = null
  142. this.autoplaySwiper = true
  143. if (!type) {
  144. setTimeout(v => {
  145. this.swiperCurrent++
  146. }, 500)
  147. }
  148. },
  149. }
  150. }
  151. </script>
  152. <style scoped>
  153. .swiper {
  154. width: 100%;
  155. height: 100%;
  156. }
  157. .swiper-image,
  158. .swiper-video {
  159. width: 100%;
  160. height: 100%;
  161. border-radius: 10rpx;
  162. object-fit: contain;
  163. }
  164. </style>