compress-video.uvue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <template>
  2. <!-- #ifdef APP -->
  3. <scroll-view style="flex:1">
  4. <!-- #endif -->
  5. <page-head :title="title"></page-head>
  6. <view>
  7. <view class="uni-padding-wrap">
  8. <video class="video" :src="beforeCompressPath" :controls="true" :poster="beforeCoverImagePath"></video>
  9. <view class="uni-title">
  10. <text class="uni-subtitle-text">压缩前视频信息</text>
  11. </view>
  12. <text>{{beforeCompressVideoInfo}}</text>
  13. <video class="video" :src="afterCompressPath" :controls="true" :poster="afterCoverImagePath"></video>
  14. <view class="uni-title">
  15. <text class="uni-subtitle-text">压缩后视频信息</text>
  16. </view>
  17. <text>{{afterCompressVideoInfo}}</text>
  18. <view class="uni-btn-v">
  19. <button type="primary" @click="chooseVideo">从相册中选取待压缩的视频</button>
  20. </view>
  21. <view class="uni-btn-v">
  22. <button type="primary" @click="compressVideo">压缩视频</button>
  23. </view>
  24. <enum-data title="压缩质量" :items="qualityItemTypes" @change="onQualityChange"></enum-data>
  25. <view class="uni-common-mt">
  26. <text class="uni-title uni-title-text">相对于原视频的分辨率比例,取值范围(0, 1]</text>
  27. <slider :min="0.1" :max="1" :step="0.1" :show-value="true" @change="onResolutionChange"></slider>
  28. </view>
  29. </view>
  30. </view>
  31. <!-- #ifdef APP -->
  32. </scroll-view>
  33. <!-- #endif -->
  34. </template>
  35. <script>
  36. import { ItemType } from '@/components/enum-data/enum-data-types';
  37. type VideoInfoForTest = {
  38. width: number;
  39. height: number;
  40. isSizeReduce: boolean;
  41. }
  42. export default {
  43. data() {
  44. return {
  45. title: "compressVideo",
  46. beforeCompressVideoInfo: "",
  47. afterCompressVideoInfo: "",
  48. beforeCompressPath: "",
  49. afterCompressPath: "",
  50. beforeCoverImagePath: "",
  51. afterCoverImagePath: "",
  52. quality: null as string | null,
  53. bitrate: null as number | null,
  54. fps: null as number | null,
  55. resolution: null as number | null,
  56. qualityItemTypes: [{ "value": 0, "name": "low(低)" }, { "value": 1, "name": "medium(中)" }, { "value": 2, "name": "high(高)" }] as ItemType[],
  57. qualityItems: ["low", "medium", "high"],
  58. // 自动化测试
  59. videoInfoForTest: null as VideoInfoForTest | null,
  60. videoSrcForTest: '/static/test-video/10second-demo.mp4',
  61. videoSrcForTestWidth: 0,
  62. videoSrcForTestHeight: 0
  63. }
  64. },
  65. methods: {
  66. compressVideo() {
  67. if (this.beforeCompressPath == "") {
  68. uni.showToast({
  69. title: "请先选择视频",
  70. icon: "error"
  71. });
  72. return;
  73. }
  74. uni.showLoading({
  75. title: "视频压缩中"
  76. });
  77. uni.compressVideo({
  78. src: this.beforeCompressPath,
  79. quality: this.quality,
  80. resolution: this.resolution,
  81. success: (res) => {
  82. console.log("compressVideo success", JSON.stringify(res));
  83. this.afterCompressPath = res.tempFilePath;
  84. uni.showToast({
  85. title: "压缩成功",
  86. icon: null
  87. });
  88. uni.getVideoInfo({
  89. src: res.tempFilePath,
  90. success: (_res) => {
  91. this.afterCompressVideoInfo = `视频画面方向: ${_res.orientation}\n视频格式: ${_res.type}\n视频长度: ${_res.duration}s\n视频大小: ${_res.size}KB\n视频宽度: ${_res.width}\n视频高度: ${_res.height}\n视频帧率: ${_res.fps}fps\n视频码率: ${_res.bitrate}kbps`;
  92. // #ifdef APP-ANDROID || APP-IOS
  93. this.afterCompressVideoInfo = this.afterCompressVideoInfo + `\n视频字节大小: ${_res.byteSize}B\n视频首帧图片路径: ${_res.thumbTempFilePath}`
  94. if(_res.thumbTempFilePath != null) {
  95. this.afterCoverImagePath = _res.thumbTempFilePath!
  96. }
  97. // #endif
  98. }
  99. });
  100. },
  101. fail: (err) => {
  102. uni.showModal({
  103. title: "压缩视频失败",
  104. content: JSON.stringify(err),
  105. showCancel: false
  106. });
  107. },
  108. complete: (_) => {
  109. uni.hideLoading();
  110. }
  111. });
  112. },
  113. chooseVideo() {
  114. uni.chooseVideo({
  115. sourceType: ["album"],
  116. compressed: false,
  117. success: (res) => {
  118. this.beforeCompressPath = res.tempFilePath;
  119. uni.getVideoInfo({
  120. src: res.tempFilePath,
  121. success: (_res) => {
  122. this.beforeCompressVideoInfo = `视频画面方向: ${_res.orientation}\n视频格式: ${_res.type}\n视频长度: ${_res.duration}s\n视频大小: ${_res.size}KB\n视频宽度: ${_res.width}\n视频高度: ${_res.height}\n视频帧率: ${_res.fps}fps\n视频码率: ${_res.bitrate}kbps`;
  123. // #ifdef APP-ANDROID || APP-IOS
  124. this.beforeCompressVideoInfo = this.beforeCompressVideoInfo + `\n视频字节大小: ${_res.byteSize}B\n视频首帧图片路径: ${_res.thumbTempFilePath}`
  125. if(_res.thumbTempFilePath != null) {
  126. this.beforeCoverImagePath = _res.thumbTempFilePath!
  127. }
  128. // #endif
  129. }
  130. });
  131. }
  132. });
  133. },
  134. onQualityChange(value : number) {
  135. this.quality = this.qualityItems[value];
  136. },
  137. onResolutionChange(event : UniSliderChangeEvent) {
  138. this.resolution = event.detail.value;
  139. },
  140. testCompressVideo() {
  141. let beforeCompressSize : number, afterComoressSize : number;
  142. uni.compressVideo({
  143. src: this.videoSrcForTest,
  144. quality: 'medium',
  145. success: (res) => {
  146. uni.getVideoInfo({
  147. src: this.videoSrcForTest,
  148. success: (_res) => {
  149. beforeCompressSize = Math.trunc(_res.size);
  150. this.videoSrcForTestWidth = _res.width
  151. this.videoSrcForTestHeight = _res.height
  152. uni.getVideoInfo({
  153. src: res.tempFilePath,
  154. success: (__res) => {
  155. afterComoressSize = Math.trunc(__res.size);
  156. this.videoInfoForTest = {
  157. "width": __res.width,
  158. "height": __res.height,
  159. "isSizeReduce": afterComoressSize < beforeCompressSize
  160. } as VideoInfoForTest;
  161. },
  162. fail(err) {
  163. console.log('>>>>>> 压缩失败', err.errMsg)
  164. }
  165. });
  166. }
  167. });
  168. },
  169. fail: (_) => {
  170. this.videoInfoForTest = null;
  171. }
  172. });
  173. }
  174. }
  175. }
  176. </script>
  177. <style>
  178. .video {
  179. align-self: center;
  180. }
  181. .image-container {
  182. flex-direction: row;
  183. }
  184. </style>