@aochuang/common 1.0.0 → 1.0.126

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. package/common/index.js +13 -0
  2. package/common/loading/index.js +7 -0
  3. package/common/loading/loading.vue +71 -0
  4. package/common/resizable/index.js +3 -0
  5. package/common/resizable/resizable.vue +260 -0
  6. package/common/scroll-load-more/index.js +3 -0
  7. package/common/scroll-load-more/scroll-load-more.vue +397 -0
  8. package/common/static-map/index.js +3 -0
  9. package/common/static-map/static-map.vue +87 -0
  10. package/common/tips/index.js +7 -0
  11. package/common/tips/tips.vue +82 -0
  12. package/common/tooltip/index.js +7 -0
  13. package/common/tooltip/popper.js +18 -0
  14. package/common/tooltip/tooltip.vue +75 -0
  15. package/common/viewer/index.js +4 -0
  16. package/common/viewer/util.js +40 -0
  17. package/common/viewer/viewer.vue +607 -0
  18. package/common/viewer-pedestal/index.js +3 -0
  19. package/common/viewer-pedestal/viewer-pedestal.vue +70 -0
  20. package/common/voice/index.js +21 -0
  21. package/common/voice/util.js +18 -0
  22. package/common/voice/voice-player-aac.js +584 -0
  23. package/common/voice/voice-player-audio.js +159 -0
  24. package/common/voice/voice-player.js +309 -0
  25. package/common/voice/voice.vue +274 -0
  26. package/common/voice-player/index.js +3 -0
  27. package/common/voice-player/voice-player.vue +785 -0
  28. package/common/waterfall/index.js +3 -0
  29. package/common/waterfall/waterfall.vue +169 -0
  30. package/common/wechat-emoji/emoji/666.png +0 -0
  31. package/common/wechat-emoji/emoji/Emm.png +0 -0
  32. package/common/wechat-emoji/emoji/OK.png +0 -0
  33. package/common/wechat-emoji/emoji//344/272/262/344/272/262.png +0 -0
  34. package/common/wechat-emoji/emoji//344/276/277/344/276/277.png +0 -0
  35. package/common/wechat-emoji/emoji//345/201/267/347/254/221.png +0 -0
  36. package/common/wechat-emoji/emoji//345/202/262/346/205/242.png +0 -0
  37. package/common/wechat-emoji/emoji//345/206/215/350/247/201.png +0 -0
  38. package/common/wechat-emoji/emoji//345/207/213/350/260/242.png +0 -0
  39. package/common/wechat-emoji/emoji//345/210/240/351/231/244.png +0 -0
  40. package/common/wechat-emoji/emoji//345/212/240/346/262/271.png +0 -0
  41. package/common/wechat-emoji/emoji//345/213/276/345/274/225.png +0 -0
  42. package/common/wechat-emoji/emoji//345/217/221/345/221/206.png +0 -0
  43. package/common/wechat-emoji/emoji//345/217/221/346/200/222.png +0 -0
  44. package/common/wechat-emoji/emoji//345/217/221/346/212/226.png +0 -0
  45. package/common/wechat-emoji/emoji//345/217/257/346/200/234.png +0 -0
  46. package/common/wechat-emoji/emoji//345/217/263/345/223/274/345/223/274.png +0 -0
  47. package/common/wechat-emoji/emoji//345/217/271/346/260/224.png +0 -0
  48. package/common/wechat-emoji/emoji//345/220/203/347/223/234.png +0 -0
  49. package/common/wechat-emoji/emoji//345/220/210/345/215/201.png +0 -0
  50. package/common/wechat-emoji/emoji//345/220/220.png +0 -0
  51. package/common/wechat-emoji/emoji//345/220/220/350/210/214/345/244/264.png +0 -0
  52. package/common/wechat-emoji/emoji//345/221/262/347/211/231.png +0 -0
  53. package/common/wechat-emoji/emoji//345/222/222/351/252/202.png +0 -0
  54. package/common/wechat-emoji/emoji//345/222/226/345/225/241.png +0 -0
  55. package/common/wechat-emoji/emoji//345/223/207.png +0 -0
  56. package/common/wechat-emoji/emoji//345/223/210/346/254/240.png +0 -0
  57. package/common/wechat-emoji/emoji//345/225/244/351/205/222.png +0 -0
  58. package/common/wechat-emoji/emoji//345/230/230.png +0 -0
  59. package/common/wechat-emoji/emoji//345/230/264/345/224/207.png +0 -0
  60. package/common/wechat-emoji/emoji//345/230/277/345/223/210.png +0 -0
  61. package/common/wechat-emoji/emoji//345/233/247.png +0 -0
  62. package/common/wechat-emoji/emoji//345/233/260.png +0 -0
  63. package/common/wechat-emoji/emoji//345/235/217/347/254/221.png +0 -0
  64. package/common/wechat-emoji/emoji//345/244/247/345/223/255.png +0 -0
  65. package/common/wechat-emoji/emoji//345/244/251/345/225/212.png +0 -0
  66. package/common/wechat-emoji/emoji//345/244/252/351/230/263.png +0 -0
  67. package/common/wechat-emoji/emoji//345/244/261/346/234/233.png +0 -0
  68. package/common/wechat-emoji/emoji//345/245/213/346/226/227.png +0 -0
  69. package/common/wechat-emoji/emoji//345/245/270/347/254/221.png +0 -0
  70. package/common/wechat-emoji/emoji//345/245/275/347/232/204.png +0 -0
  71. package/common/wechat-emoji/emoji//345/247/224/345/261/210.png +0 -0
  72. package/common/wechat-emoji/emoji//345/256/263/347/276/236.png +0 -0
  73. package/common/wechat-emoji/emoji//345/260/264/345/260/254.png +0 -0
  74. package/common/wechat-emoji/emoji//345/267/246/345/223/274/345/223/274.png +0 -0
  75. package/common/wechat-emoji/emoji//345/272/206/347/245/235.png +0 -0
  76. package/common/wechat-emoji/emoji//345/274/261.png +0 -0
  77. package/common/wechat-emoji/emoji//345/274/272.png +0 -0
  78. package/common/wechat-emoji/emoji//345/276/227/346/204/217.png +0 -0
  79. package/common/wechat-emoji/emoji//345/276/256/347/254/221.png +0 -0
  80. package/common/wechat-emoji/emoji//345/277/203/347/242/216.png +0 -0
  81. package/common/wechat-emoji/emoji//345/277/253/345/223/255/344/272/206.png +0 -0
  82. package/common/wechat-emoji/emoji//346/200/204/347/201/253.png +0 -0
  83. package/common/wechat-emoji/emoji//346/201/220/346/203/247.png +0 -0
  84. package/common/wechat-emoji/emoji//346/202/240/351/227/262.png +0 -0
  85. package/common/wechat-emoji/emoji//346/203/212/346/201/220.png +0 -0
  86. package/common/wechat-emoji/emoji//346/203/212/350/256/266.png +0 -0
  87. package/common/wechat-emoji/emoji//346/204/211/345/277/253.png +0 -0
  88. package/common/wechat-emoji/emoji//346/206/250/347/254/221.png +0 -0
  89. package/common/wechat-emoji/emoji//346/211/223/350/204/270.png +0 -0
  90. package/common/wechat-emoji/emoji//346/212/223/347/213/202.png +0 -0
  91. package/common/wechat-emoji/emoji//346/212/240/351/274/273.png +0 -0
  92. package/common/wechat-emoji/emoji//346/212/261/346/213/263.png +0 -0
  93. package/common/wechat-emoji/emoji//346/213/245/346/212/261.png +0 -0
  94. package/common/wechat-emoji/emoji//346/213/263/345/244/264.png +0 -0
  95. package/common/wechat-emoji/emoji//346/215/202/350/204/270.png +0 -0
  96. package/common/wechat-emoji/emoji//346/217/241/346/211/213.png +0 -0
  97. package/common/wechat-emoji/emoji//346/222/207/345/230/264.png +0 -0
  98. package/common/wechat-emoji/emoji//346/223/246/346/261/227.png +0 -0
  99. package/common/wechat-emoji/emoji//346/225/262/346/211/223.png +0 -0
  100. package/common/wechat-emoji/emoji//346/227/240/350/257/255.png +0 -0
  101. package/common/wechat-emoji/emoji//346/227/272/346/237/264.png +0 -0
  102. package/common/wechat-emoji/emoji//346/231/225.png +0 -0
  103. package/common/wechat-emoji/emoji//346/234/210/344/272/256.png +0 -0
  104. package/common/wechat-emoji/emoji//346/234/272/346/231/272.png +0 -0
  105. package/common/wechat-emoji/emoji//346/261/227.png +0 -0
  106. package/common/wechat-emoji/emoji//346/265/201/346/261/227.png +0 -0
  107. package/common/wechat-emoji/emoji//346/265/201/346/263/252.png +0 -0
  108. package/common/wechat-emoji/emoji//347/202/270/345/274/271.png +0 -0
  109. package/common/wechat-emoji/emoji//347/203/237/350/212/261.png +0 -0
  110. package/common/wechat-emoji/emoji//347/210/206/347/253/271.png +0 -0
  111. package/common/wechat-emoji/emoji//347/210/261/345/277/203.png +0 -0
  112. package/common/wechat-emoji/emoji//347/214/252/345/244/264.png +0 -0
  113. package/common/wechat-emoji/emoji//347/216/253/347/221/260.png +0 -0
  114. package/common/wechat-emoji/emoji//347/224/237/347/227/205.png +0 -0
  115. package/common/wechat-emoji/emoji//347/226/221/351/227/256.png +0 -0
  116. package/common/wechat-emoji/emoji//347/231/274.png +0 -0
  117. package/common/wechat-emoji/emoji//347/231/275/347/234/274.png +0 -0
  118. package/common/wechat-emoji/emoji//347/232/261/347/234/211.png +0 -0
  119. package/common/wechat-emoji/emoji//347/235/241.png +0 -0
  120. package/common/wechat-emoji/emoji//347/240/264/346/266/225/344/270/272/347/254/221.png +0 -0
  121. package/common/wechat-emoji/emoji//347/244/274/347/211/251.png +0 -0
  122. package/common/wechat-emoji/emoji//347/244/276/344/274/232/347/244/276/344/274/232.png +0 -0
  123. package/common/wechat-emoji/emoji//347/246/217.png +0 -0
  124. package/common/wechat-emoji/emoji//347/254/221/350/204/270.png +0 -0
  125. package/common/wechat-emoji/emoji//347/272/242/345/214/205.png +0 -0
  126. package/common/wechat-emoji/emoji//347/277/273/347/231/275/347/234/274.png +0 -0
  127. package/common/wechat-emoji/emoji//350/200/266.png +0 -0
  128. package/common/wechat-emoji/emoji//350/203/234/345/210/251.png +0 -0
  129. package/common/wechat-emoji/emoji//350/204/270/347/272/242.png +0 -0
  130. package/common/wechat-emoji/emoji//350/211/262.png +0 -0
  131. package/common/wechat-emoji/emoji//350/213/246/346/266/251.png +0 -0
  132. package/common/wechat-emoji/emoji//350/217/234/345/210/200.png +0 -0
  133. package/common/wechat-emoji/emoji//350/233/213/347/263/225.png +0 -0
  134. package/common/wechat-emoji/emoji//350/241/260.png +0 -0
  135. package/common/wechat-emoji/emoji//350/243/202/345/274/200.png +0 -0
  136. package/common/wechat-emoji/emoji//350/245/277/347/223/234.png +0 -0
  137. package/common/wechat-emoji/emoji//350/256/251/346/210/221/347/234/213/347/234/213.png +0 -0
  138. package/common/wechat-emoji/emoji//350/260/203/347/232/256.png +0 -0
  139. package/common/wechat-emoji/emoji//350/267/263/350/267/263.png +0 -0
  140. package/common/wechat-emoji/emoji//350/275/254/345/234/210.png +0 -0
  141. package/common/wechat-emoji/emoji//351/204/231/350/247/206.png +0 -0
  142. package/common/wechat-emoji/emoji//351/227/255/345/230/264.png +0 -0
  143. package/common/wechat-emoji/emoji//351/230/264/351/231/251.png +0 -0
  144. package/common/wechat-emoji/emoji//351/232/276/350/277/207.png +0 -0
  145. package/common/wechat-emoji/emoji//351/252/267/351/253/205.png +0 -0
  146. package/common/wechat-emoji/emoji//351/254/274/350/204/270.png +0 -0
  147. package/common/wechat-emoji/emoji//351/270/241.png +0 -0
  148. package/common/wechat-emoji/emoji//351/274/223/346/216/214.png +0 -0
  149. package/common/wechat-emoji/index.js +14 -0
  150. package/common/wechat-emoji/order.json +111 -0
  151. package/common/wechat-emoji/utils.js +52 -0
  152. package/common/wechat-emoji/wechat-emoji.vue +74 -0
  153. package/common/wechat-emoji-select/index.js +3 -0
  154. package/common/wechat-emoji-select/wechat-emoji-select.vue +67 -0
  155. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item-boolean.vue +33 -0
  156. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item-date-range.vue +30 -0
  157. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item-date.vue +41 -0
  158. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item-datetime-range.vue +34 -0
  159. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item-datetime.vue +41 -0
  160. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item-number-range.vue +67 -0
  161. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item-number.vue +35 -0
  162. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item-string.vue +41 -0
  163. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item-value.vue +73 -0
  164. package/components/advanced-filter/advanced-filter-condition-item/advanced-filter-condition-item.vue +226 -0
  165. package/components/advanced-filter/advanced-filter-condition-toggle.vue +112 -0
  166. package/components/advanced-filter/advanced-filter-condition.vue +352 -0
  167. package/components/advanced-filter/advanced-filter-permanent-item.vue +10 -0
  168. package/components/advanced-filter/advanced-filter-permanent.vue +10 -0
  169. package/components/advanced-filter/advanced-filter-scene-form.vue +95 -0
  170. package/components/advanced-filter/advanced-filter-scene-item.vue +64 -0
  171. package/components/advanced-filter/advanced-filter-scene-manage.vue +264 -0
  172. package/components/advanced-filter/advanced-filter-scene-transfer.vue +283 -0
  173. package/components/advanced-filter/advanced-filter-scene.vue +199 -0
  174. package/components/advanced-filter/advanced-filter.vue +119 -0
  175. package/components/advanced-filter/index.js +35 -0
  176. package/components/advanced-filter/utils.js +132 -0
  177. package/components/autocomplete/autocomplete.vue +121 -0
  178. package/components/autocomplete/index.js +7 -0
  179. package/components/avatar/avatar.png +0 -0
  180. package/components/avatar/avatar.vue +216 -0
  181. package/components/avatar/index.js +7 -0
  182. package/components/brick-wall/brick-wall-skeleton.vue +125 -0
  183. package/components/brick-wall/brick-wall.vue +293 -0
  184. package/components/brick-wall/index.js +7 -0
  185. package/components/button/button.vue +550 -0
  186. package/components/button/index.js +7 -0
  187. package/components/button/utils.js +20 -0
  188. package/components/cascader/cascader.vue +184 -0
  189. package/components/cascader/index.js +7 -0
  190. package/components/cascader/util.js +50 -0
  191. package/components/checkbox/checkbox.vue +114 -0
  192. package/components/checkbox/index.js +7 -0
  193. package/components/checkbox-button/index.js +8 -0
  194. package/components/checkbox-group/checkbox-group.vue +11 -0
  195. package/components/checkbox-group/index.js +7 -0
  196. package/components/date-picker/date-picker.vue +307 -0
  197. package/components/date-picker/index.js +7 -0
  198. package/components/dialog/dialog.vue +187 -0
  199. package/components/dialog/index.js +14 -0
  200. package/components/dialog/utils.js +20 -0
  201. package/components/drawer/drawer.vue +186 -0
  202. package/components/drawer/index.js +14 -0
  203. package/components/drawer/utils.js +36 -0
  204. package/components/dropdown/dropdown-item.vue +71 -0
  205. package/components/dropdown/dropdown.vue +326 -0
  206. package/components/dropdown/index.js +16 -0
  207. package/components/empty/empty.vue +89 -0
  208. package/components/empty/index.js +7 -0
  209. package/components/filter/filter-group.vue +44 -0
  210. package/components/filter/filter-item.vue +122 -0
  211. package/components/filter/filter-more.vue +114 -0
  212. package/components/filter/filter.vue +407 -0
  213. package/components/filter/index.js +20 -0
  214. package/components/filter/refresh-line.svg +1 -0
  215. package/components/filter/util.js +5 -0
  216. package/components/form/form-cell.vue +231 -0
  217. package/components/form/form-group.vue +147 -0
  218. package/components/form/form-row.vue +51 -0
  219. package/components/form/form.vue +287 -0
  220. package/components/form/index.js +24 -0
  221. package/components/grid/grid-card-view/grid-card-view.vue +157 -0
  222. package/components/grid/grid-column.vue +137 -0
  223. package/components/grid/grid-filter/grid-filter-group.vue +41 -0
  224. package/components/grid/grid-filter/grid-filter-item.vue +68 -0
  225. package/components/grid/grid-filter/grid-filter.vue +115 -0
  226. package/components/grid/grid-filter/util.js +7 -0
  227. package/components/grid/grid-filter-operate/grid-filter-operate-item.vue +55 -0
  228. package/components/grid/grid-filter-operate/grid-filter-operate.vue +46 -0
  229. package/components/grid/grid-sort/grid-sort-proxy.js +27 -0
  230. package/components/grid/grid-sort/grid-sort.vue +205 -0
  231. package/components/grid/grid-sort/icons/asc.png +0 -0
  232. package/components/grid/grid-sort/icons/desc.png +0 -0
  233. package/components/grid/grid-sort/index.js +7 -0
  234. package/components/grid/grid-table-view/grid-table-view.vue +178 -0
  235. package/components/grid/grid-table.vue +549 -0
  236. package/components/grid/grid-toolbar/grid-batch-toolbar-proxy.js +21 -0
  237. package/components/grid/grid-toolbar/grid-batch-toolbar.vue +129 -0
  238. package/components/grid/grid-toolbar/grid-global-toolbar-proxy.js +21 -0
  239. package/components/grid/grid-toolbar/grid-global-toolbar.vue +37 -0
  240. package/components/grid/grid-toolbar/grid-more-toolbar-proxy.js +21 -0
  241. package/components/grid/grid-toolbar/grid-more-toolbar.vue +138 -0
  242. package/components/grid/grid-toolbar/grid-row-toolbar.vue +279 -0
  243. package/components/grid/grid-view-select.vue +78 -0
  244. package/components/grid/grid.vue +1114 -0
  245. package/components/grid/icons/more-line.svg +1 -0
  246. package/components/grid/icons/refresh.svg +14 -0
  247. package/components/grid/index.js +60 -0
  248. package/components/grid/util.js +31 -0
  249. package/components/icon/demo.css +539 -0
  250. package/components/icon/demo_index.html +9112 -0
  251. package/components/icon/icon.vue +96 -0
  252. package/components/icon/iconfont.css +1567 -0
  253. package/components/icon/iconfont.eot +0 -0
  254. package/components/icon/iconfont.js +1 -0
  255. package/components/icon/iconfont.json +2725 -0
  256. package/components/icon/iconfont.svg +455 -0
  257. package/components/icon/iconfont.ttf +0 -0
  258. package/components/icon/iconfont.woff +0 -0
  259. package/components/icon/iconfont.woff2 +0 -0
  260. package/components/icon/index.js +7 -0
  261. package/components/image/image.vue +377 -0
  262. package/components/image/index.js +14 -0
  263. package/components/image/util.js +107 -0
  264. package/components/index.js +157 -0
  265. package/components/loading/index.js +7 -0
  266. package/components/loading/loading.vue +130 -0
  267. package/components/menu/index.js +20 -0
  268. package/components/menu/menu-group.vue +245 -0
  269. package/components/menu/menu-item.vue +269 -0
  270. package/components/menu/menu.vue +64 -0
  271. package/components/message/index.js +19 -0
  272. package/components/message/message.js +31 -0
  273. package/components/message/message.less +6 -0
  274. package/components/message-box/index.js +14 -0
  275. package/components/message-box/message-box.js +140 -0
  276. package/components/message-box/message-box.less +5 -0
  277. package/components/pagination/index.js +7 -0
  278. package/components/pagination/pagination.vue +197 -0
  279. package/components/panel/index.js +7 -0
  280. package/components/panel/panel.vue +44 -0
  281. package/components/popover/index.js +7 -0
  282. package/components/popover/popover.vue +163 -0
  283. package/components/popup-select/index.js +7 -0
  284. package/components/popup-select/popup-select.vue +114 -0
  285. package/components/radio/index.js +7 -0
  286. package/components/radio/radio.vue +92 -0
  287. package/components/radio-button/index.js +7 -0
  288. package/components/radio-button/radio-button.vue +20 -0
  289. package/components/radio-group/index.js +7 -0
  290. package/components/radio-group/radio-group.vue +22 -0
  291. package/components/searchbox/index.js +7 -0
  292. package/components/searchbox/searchbox.vue +272 -0
  293. package/components/select/index.js +11 -0
  294. package/components/select/select-load-more.vue +53 -0
  295. package/components/select/select.vue +578 -0
  296. package/components/skeleton/index.js +16 -0
  297. package/components/skeleton/skeleton-rows.vue +52 -0
  298. package/components/skeleton/skeleton.vue +72 -0
  299. package/components/sortable/index.js +11 -0
  300. package/components/sortable/sortable-item.vue +77 -0
  301. package/components/sortable/sortable.vue +67 -0
  302. package/components/spinner/index.js +7 -0
  303. package/components/spinner/spinner.vue +121 -0
  304. package/components/spinner-range/index.js +7 -0
  305. package/components/spinner-range/spinner-range.vue +97 -0
  306. package/components/spinner-textarea/index.js +7 -0
  307. package/components/spinner-textarea/spinner-textarea.vue +65 -0
  308. package/components/switch/index.js +7 -0
  309. package/components/switch/switch.vue +105 -0
  310. package/components/tabbar/index.js +9 -0
  311. package/components/tabbar/tabbar-item.vue +162 -0
  312. package/components/tabbar/tabbar.vue +49 -0
  313. package/components/tabs/index.js +12 -0
  314. package/components/tabs/tabs.vue +120 -0
  315. package/components/tag/index.js +9 -0
  316. package/components/tag/tag.less +39 -0
  317. package/components/text/index.js +7 -0
  318. package/components/text/text.vue +69 -0
  319. package/components/textarea/index.js +7 -0
  320. package/components/textarea/textarea.vue +245 -0
  321. package/components/textbox/index.js +7 -0
  322. package/components/textbox/textbox.vue +275 -0
  323. package/components/time-picker/index.js +7 -0
  324. package/components/time-picker/time-picker.vue +84 -0
  325. package/components/toolbar/index.js +16 -0
  326. package/components/toolbar/toolbar-item.vue +43 -0
  327. package/components/toolbar/toolbar.vue +81 -0
  328. package/components/tooltip/index.js +9 -0
  329. package/components/tooltip/tooltip.vue +86 -0
  330. package/components/transfer/index.js +7 -0
  331. package/components/transfer/transfer-element.vue +109 -0
  332. package/components/transfer/transfer-load-more.vue +53 -0
  333. package/components/transfer/transfer.vue +260 -0
  334. package/components/tree/index.js +7 -0
  335. package/components/tree/tree.vue +485 -0
  336. package/components/tree/utils.js +122 -0
  337. package/components/video/index.js +7 -0
  338. package/components/video/video.vue +101 -0
  339. package/package.json +15 -1
  340. package/uni-common/more-button/more-button.vue +23 -0
  341. package/uni-common/popup-select/popup-select.vue +217 -0
  342. package/uni-common/portray/portray.vue +54 -0
  343. package/uni-common/refresh-view/refresh-view.vue +94 -0
  344. package/uni-common/scroll-load-more/scroll-load-more.vue +201 -0
  345. package/uni-common/tree-popup-select/index.js +3 -0
  346. package/uni-common/tree-popup-select/tree-popup-select-panel.vue +92 -0
  347. package/uni-common/tree-popup-select/tree-popup-select.vue +124 -0
  348. package/uni-common/tree-popup-select/util.js +19 -0
  349. package/uni-common/wechat-emoji/index.js +13 -0
  350. package/uni-common/wechat-emoji/order.json +438 -0
  351. package/uni-common/wechat-emoji/utils.js +52 -0
  352. package/uni-common/wechat-emoji/wechat-emoji.vue +74 -0
  353. package/uni-components/avatar/avatar.vue +81 -0
  354. package/uni-components/badge/badge.vue +57 -0
  355. package/uni-components/empty/empty.vue +27 -0
  356. package/uni-components/exception/exception.vue +47 -0
  357. package/uni-components/icon/demo.css +539 -0
  358. package/uni-components/icon/demo_index.html +1591 -0
  359. package/uni-components/icon/icon.vue +48 -0
  360. package/uni-components/icon/iconfont.css +259 -0
  361. package/uni-components/icon/iconfont.js +1 -0
  362. package/uni-components/icon/iconfont.json +436 -0
  363. package/uni-components/icon/iconfont.ttf +0 -0
  364. package/uni-components/icon/iconfont.woff +0 -0
  365. package/uni-components/icon/iconfont.woff2 +0 -0
  366. package/uni-components/icon/index.js +3 -0
  367. package/uni-components/image/image.vue +38 -0
  368. package/uni-components/image/index.js +3 -0
  369. package/uni-components/loading/index.js +3 -0
  370. package/uni-components/loading/loading.vue +30 -0
  371. package/uni-components/message/message-item.vue +29 -0
  372. package/uni-components/message/message.js +80 -0
  373. package/uni-components/message/message.vue +30 -0
  374. package/uni-components/message-box/message-box-item.vue +54 -0
  375. package/uni-components/message-box/message-box.js +91 -0
  376. package/uni-components/message-box/message-box.vue +52 -0
  377. package/uni-components/picker/picker.vue +270 -0
  378. package/uni-components/popup/index.js +3 -0
  379. package/uni-components/popup/popup.vue +143 -0
  380. package/uni-components/search/index.js +3 -0
  381. package/uni-components/search/search.vue +86 -0
  382. package/uni-components/skeleton/skeleton-chat.vue +85 -0
  383. package/uni-components/skeleton/skeleton-contact.vue +84 -0
  384. package/uni-components/skeleton/skeleton-detail.vue +84 -0
  385. package/uni-components/skeleton/skeleton.vue +32 -0
  386. package/uni-components/tabbar/tabbar-item.vue +33 -0
  387. package/uni-components/tabbar/tabbar.vue +87 -0
  388. package/uni-components/tree/index.js +3 -0
  389. package/uni-components/tree/tree-select-loading.vue +48 -0
  390. package/uni-components/tree/tree-select-node.vue +202 -0
  391. package/uni-components/tree/tree-select-store.js +520 -0
  392. package/uni-components/tree/tree-select.vue +210 -0
  393. package/uni-components/tree/utils.js +33 -0
  394. package/uni-components/video/index.js +3 -0
  395. package/uni-components/video/video.vue +29 -0
  396. package/uni-components/voice/index.js +3 -0
  397. package/uni-components/voice/voice.vue +24 -0
  398. package/uni-components/waterfall/index.js +3 -0
  399. package/uni-components/waterfall/util.js +72 -0
  400. package/uni-components/waterfall/waterfall.vue +147 -0
  401. package/utils/data.js +128 -0
  402. package/utils/date.js +495 -0
  403. package/utils/dom.js +37 -0
  404. package/utils/emitter.js +3 -0
  405. package/utils/event.js +92 -0
  406. package/utils/file.js +76 -0
  407. package/utils/json.js +40 -0
  408. package/utils/network-detector.js +258 -0
  409. package/utils/oss.js +11 -0
  410. package/utils/resize-event.js +35 -0
  411. package/utils/share-message.js +81 -0
  412. package/utils/share-websocket.js +127 -0
  413. package/utils/string.js +59 -0
  414. package/utils/time-task.js +60 -0
  415. package/utils/url.js +46 -0
  416. package/utils/util.js +427 -0
  417. package/utils/utils.js +0 -0
@@ -0,0 +1,21 @@
1
+ import Voice from './voice'
2
+
3
+ export { setAacCodecParserLibPath, getAacCodecParserLibPath, setBenzAMRRecorderLibPath, getBenzAMRRecorderLibPath } from './util'
4
+
5
+ export function getRateOptions () {
6
+ return [{
7
+ value: 1,
8
+ showText: '1倍',
9
+ text: '1倍(默认)'
10
+ }, {
11
+ value: 1.25,
12
+ showText: '1.5倍',
13
+ text: '1.5倍'
14
+ }, {
15
+ value: 1.5,
16
+ showText: '2倍',
17
+ text: '2倍'
18
+ }]
19
+ }
20
+
21
+ export default Voice
@@ -0,0 +1,18 @@
1
+ let aacCodecParserLibPath = './lib/aac-codec-parser/aac-codec-parser.js'
2
+ let benzAMRRecorderLibPath = '/lib/ac-amr-recorder/BenzAMRRecorder.js'
3
+
4
+ export function setAacCodecParserLibPath (libPath) {
5
+ aacCodecParserLibPath = libPath
6
+ }
7
+
8
+ export function getAacCodecParserLibPath () {
9
+ return aacCodecParserLibPath
10
+ }
11
+
12
+ export function setBenzAMRRecorderLibPath (libPath) {
13
+ benzAMRRecorderLibPath = libPath
14
+ }
15
+
16
+ export function getBenzAMRRecorderLibPath () {
17
+ return benzAMRRecorderLibPath
18
+ }
@@ -0,0 +1,584 @@
1
+ import { loadScript } from '../../utils/file'
2
+ import { getAacCodecParserLibPath } from './util'
3
+ import axios from 'axios'
4
+
5
+ async function appendBuffer(sourceBuffer, buffer) {
6
+ if (sourceBuffer.updating) {
7
+ await new Promise(resolve => {
8
+ sourceBuffer.addEventListener('updateend', resolve, { once: true });
9
+ });
10
+ }
11
+
12
+ sourceBuffer.appendBuffer(buffer);
13
+
14
+ return new Promise(resolve => {
15
+ sourceBuffer.addEventListener('updateend', resolve, { once: true });
16
+ });
17
+ }
18
+
19
+ export default class VoicePlayerAAC {
20
+ constructor(options) {
21
+ this.options = Object.assign({}, {
22
+ playRate: 1,
23
+ onPlaying: null,
24
+ onEnded: null,
25
+ onPlay: null,
26
+ onError: null,
27
+ onPause: null,
28
+ bitrateKbps: 195.02 // 新增:开放码率校准入口,用户可根据实际音频调整
29
+ }, options)
30
+
31
+ this.$audio = document.createElement('audio')
32
+ this.$audio.autoplay = false
33
+ this._timer = null
34
+ this._playbackRate = 1
35
+ this._currPosition = 0
36
+ this._url = ''
37
+ this._play = false
38
+
39
+ // MSE 核心变量
40
+ this.currentMediaSource = null
41
+ this.mediaSourceSrc = null
42
+ this.currentObjectUrl = null
43
+ this.sourceBuffer = null
44
+ this.iterator = null
45
+ this.wrapper = null
46
+ this.audioData = null
47
+ this.estimatedDuration = 0
48
+ this.bufferCleaner = null
49
+ this.loadNextSegment = false
50
+ this.isPlaying = false
51
+ this.isPreloading = false
52
+ this.lastSeekTarget = null
53
+ this.downloading = false
54
+
55
+ // 并发控制锁
56
+ this.isSeeking = false // 拖拽操作锁
57
+ this.seekDebounceTimer = null // 拖拽防抖定时器
58
+
59
+ this.bindAudioEvents()
60
+ }
61
+
62
+ // 大于18M走分片解析逻辑
63
+ isUseBigFile (audioData) {
64
+ if (!audioData) {
65
+ return false
66
+ }
67
+ return audioData.byteLength > 18 * 1024 * 1024; // 18MB字节阈值
68
+ }
69
+
70
+ bindAudioEvents() {
71
+ this.$audio.onplaying = () => {
72
+ let totalPosition = this.$audio.duration
73
+ if (this.isUseBigFile(this.audioData)) {
74
+ totalPosition = this.estimatedDuration
75
+ }
76
+ clearInterval(this._timer)
77
+ this._timer = setInterval(() => {
78
+ if (!this._play) return
79
+ const currPosition = this.$audio.currentTime
80
+ this.options.onPlaying?.({
81
+ currPosition,
82
+ totalPosition
83
+ })
84
+ if (currPosition >= totalPosition) {
85
+ clearInterval(this._timer)
86
+ this.stop()
87
+ }
88
+ }, 100)
89
+ }
90
+ this.$audio.onplay = () => {
91
+ this.options.onPlay?.()
92
+ }
93
+
94
+ this.$audio.onended = () => {
95
+ // 有时候还没播放完就触发了这个事件,导致进度条有问题
96
+ this.options.onPlaying && this.options.onPlaying({
97
+ currPosition: Math.min(this.$audio.currentTime, this.$audio.duration),
98
+ totalPosition: this.$audio.duration
99
+ })
100
+ clearInterval(this._timer)
101
+ this.stop()
102
+ }
103
+
104
+ this.$audio.addEventListener('stop', () => {
105
+ clearInterval(this._timer)
106
+ this.options.onEnded?.()
107
+ })
108
+
109
+ this.$audio.addEventListener('error', (e) => {
110
+ console.error('Audio error:', this.$audio.error)
111
+ this.options.onError?.({
112
+ type: 'aac',
113
+ url: this._url,
114
+ message: this.$audio.error || '未知音频错误'
115
+ })
116
+ })
117
+ }
118
+
119
+ getScript() {
120
+ return new Promise((resolve, reject) => {
121
+ if (window.MSEAudioWrapper) {
122
+ resolve(window.MSEAudioWrapper)
123
+ } else {
124
+ loadScript(getAacCodecParserLibPath())
125
+ .then(() => resolve(window.MSEAudioWrapper))
126
+ .catch(reject)
127
+ }
128
+ })
129
+ }
130
+
131
+ setPlaybackRate(rate) {
132
+ if (typeof rate !== 'number') {
133
+ throw new Error('播放倍率必须为数字类型')
134
+ }
135
+ this.stop()
136
+ this._playbackRate = rate
137
+ this.$audio.playbackRate = rate
138
+ }
139
+
140
+ async setPosition(position) {
141
+ if (position === this._currPosition) return
142
+ this._currPosition = position
143
+ if (this.isUseBigFile(this.audioData)) {
144
+ clearTimeout(this.seekDebounceTimer)
145
+ this.seekDebounceTimer = setTimeout(async () => {
146
+ const targetTime = Math.max(0, Math.min(position, this.estimatedDuration))
147
+ console.log('[setPosition] 防抖后执行跳转:', targetTime)
148
+ await this.seekToTime(targetTime, targetTime < this.$audio.currentTime)
149
+ }, 300)
150
+ } else {
151
+ this.$audio.currentTime = position
152
+ }
153
+ }
154
+
155
+ setUrl(url, cb) {
156
+ if (this._url !== url) {
157
+ this._url = url
158
+ this.clearMediaResources()
159
+ }
160
+ if (!url) {
161
+ this.stop()
162
+ }
163
+ cb?.({ status: 'success' })
164
+ }
165
+
166
+ start() {
167
+ return this.getScript().then(() => {
168
+ if (this._play || !this._url) return
169
+ this._play = true
170
+ this.downloading = true
171
+ if (this.abortController) {
172
+ // 切换音频时,先取消上一个未完成的请求
173
+ this.abortController.abort()
174
+ }
175
+ this.abortController = new AbortController()
176
+ const { signal } = this.abortController
177
+ let ps = null
178
+ if (this.audioData) {
179
+ ps = Promise.resolve(this.audioData)
180
+ } else {
181
+ ps = axios.get(this._url, {
182
+ responseType: 'arraybuffer',
183
+ signal: signal
184
+ }).then((response) => {
185
+ const arrayBuffer = response.data
186
+ const audioData = new Uint8Array(arrayBuffer)
187
+ return audioData
188
+ })
189
+ }
190
+ return ps.then((audioData) => {
191
+ try {
192
+ this.clearMediaResources()
193
+ this.audioData = audioData
194
+ console.log('音频数据加载完成,大小:', this.audioData.byteLength)
195
+ this.estimatedDuration = this.calculateEstimatedDuration(this.audioData.byteLength)
196
+ console.log('预估总时长:', this.estimatedDuration.toFixed(2), 's | 使用码率:', this.options.bitrateKbps, 'kbps')
197
+ this.mediaSource = new MediaSource()
198
+ this.currentMediaSource = this.mediaSource
199
+ this.mediaSourceSrc = URL.createObjectURL(this.mediaSource)
200
+ this.currentObjectUrl = this.mediaSourceSrc
201
+ this.$audio.src = this.mediaSourceSrc
202
+ if (this.isUseBigFile(this.audioData)) {
203
+ this.$audio.addEventListener('waiting', async () => {
204
+ if (!this.isSeeking) {
205
+ console.log('检测到缓冲不足,补充10秒缓冲...')
206
+ await this.forcePreload(10)
207
+ }
208
+ }, { passive: true })
209
+ this.$audio.addEventListener('playing', () => this.isPlaying = true)
210
+ this.$audio.addEventListener('pause', () => this.isPlaying = false)
211
+ this.mediaSource.addEventListener('sourceerror', (e) => {
212
+ console.error('媒体源错误:', e)
213
+ this.options.onError?.({ type: 'mse', url: this._url, message: e })
214
+ })
215
+ this.mediaSource.addEventListener('sourceopen', async () => {
216
+ if (!this._play) return
217
+ try {
218
+ const MIME_TYPE = 'audio/aac; codecs=mp4a.40.2'
219
+ this.wrapper = new window.MSEAudioWrapper(MIME_TYPE)
220
+ this.iterator = this.wrapper.iterator(this.audioData)
221
+ this.sourceBuffer = this.mediaSource.addSourceBuffer(this.wrapper.mimeType || MIME_TYPE)
222
+ this.sourceBuffer.mode = 'sequence'
223
+ console.log('SourceBuffer 初始化完成,模式:', this.sourceBuffer.mode)
224
+ const initialSegments = []
225
+ for (let i = 0; i < 15; i++) {
226
+ const { value, done } = this.iterator.next()
227
+ if (done) break
228
+ initialSegments.push(value)
229
+ }
230
+ for (const seg of initialSegments) {
231
+ await this.appendBufferSafe(this.sourceBuffer, seg)
232
+ }
233
+ console.log('初始缓冲加载完成 | 缓冲范围:', this.getBufferedRange())
234
+ this.$audio.currentTime = 0
235
+ await this.$audio.play()
236
+ this.isPlaying = true
237
+ this.bufferCleaner = setInterval(async () => {
238
+ if (this.isSeeking || !this.sourceBuffer || this.sourceBuffer.buffered.length === 0) return
239
+ const currentTime = this.$audio.currentTime
240
+ const [bufferStart, bufferEnd] = this.getBufferedRange()
241
+ if (this.isPlaying && bufferEnd - bufferStart > 15) {
242
+ const cleanEnd = Math.max(currentTime - 5, bufferStart)
243
+ if (bufferStart < cleanEnd && cleanEnd <= bufferEnd) {
244
+ try {
245
+ await this.safeRemoveBuffer(this.sourceBuffer, bufferStart, cleanEnd)
246
+ } catch (err) {
247
+ console.warn('清理缓冲失败,跳过本次操作:', err)
248
+ }
249
+ }
250
+ }
251
+ if (bufferEnd - currentTime < 8 && !this.loadNextSegment && !this.isPreloading) {
252
+ this.loadNextSegment = true
253
+ try {
254
+ const { value: segment, done } = this.iterator.next()
255
+ if (!done) {
256
+ await this.appendBufferSafe(this.sourceBuffer, segment)
257
+ } else {
258
+ this.mediaSource.endOfStream()
259
+ }
260
+ } catch (err) {
261
+ console.error('加载分片失败:', err)
262
+ } finally {
263
+ this.loadNextSegment = false
264
+ }
265
+ }
266
+
267
+ if (!this.isPlaying && bufferEnd - currentTime < 5 && !this.isPreloading) {
268
+ const { value: segment, done } = this.iterator.next()
269
+ if (!done) {
270
+ await this.appendBufferSafe(this.sourceBuffer, segment)
271
+ }
272
+ }
273
+ }, 500)
274
+
275
+ } catch (e) {
276
+ console.error('MSE 初始化失败:', e)
277
+ this.options.onError?.({ type: 'mse', url: this._url, message: e })
278
+ }
279
+ }, { once: true })
280
+ this.$audio.play().catch(err => console.log('等待缓冲中:', err.message))
281
+ } else {
282
+ this.mediaSource.addEventListener('sourceopen', async () => {
283
+ if (!this._play) {
284
+ return
285
+ }
286
+ try {
287
+ this.wrapper = new window.MSEAudioWrapper('audio/aac');
288
+ this.sourceBuffer = null;
289
+ let segmentCount = 0;
290
+ let totalBytesProcessed = 0;
291
+ for (const segment of this.wrapper.iterator(this.audioData)) {
292
+ segmentCount++;
293
+ totalBytesProcessed += segment.byteLength;
294
+ console.log(`Processing segment ${segmentCount}, size: ${segment.byteLength}`);
295
+ if (!this.sourceBuffer) {
296
+ if (this.wrapper.mimeType) {
297
+ console.log('Creating SourceBuffer with mimeType:', this.wrapper.mimeType);
298
+ this.sourceBuffer = this.mediaSource.addSourceBuffer(this.wrapper.mimeType);
299
+ console.log('Default SourceBuffer mode:', this.sourceBuffer.mode);
300
+ this.sourceBuffer.mode = 'sequence'; // Critical for timeline placement
301
+ console.log('Set SourceBuffer mode to:', this.sourceBuffer.mode);
302
+ } else {
303
+ throw new Error('MimeType not determined yet');
304
+ }
305
+ }
306
+ await appendBuffer(this.sourceBuffer, segment);
307
+ }
308
+ console.log(`Finished processing. Total segments: ${segmentCount}, Total bytes: ${totalBytesProcessed}`);
309
+ this.mediaSource.endOfStream();
310
+ if (this.sourceBuffer && this.sourceBuffer.buffered.length > 0) {
311
+ const buffered = this.sourceBuffer.buffered;
312
+ console.log(`Buffered range: ${buffered.start(0)} - ${buffered.end(0)}`);
313
+ console.log(`Audio duration: ${this.$audio.duration}`);
314
+ }
315
+ this.$audio.play()
316
+ } catch (e) {
317
+ console.error(e);
318
+ this.options.onError && this.options.onError({
319
+ type: 'aac',
320
+ url: this._url,
321
+ message: e ? e.message : '未知错误'
322
+ })
323
+ }
324
+ })
325
+ }
326
+ } catch (err) {
327
+ console.error('音频播放全局错误:', err)
328
+ this.options.onError?.({ type: 'global', url: this._url, message: err })
329
+ }
330
+ }).finally(() => {
331
+ this.downloading = false
332
+ })
333
+ })
334
+ }
335
+
336
+ async safeRemoveBuffer(sourceBuffer, start, end, retries = 3, delay = 500) {
337
+ for (let i = 0; i < retries; i++) {
338
+ try {
339
+ if (sourceBuffer.updating) {
340
+ await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve, { once: true }))
341
+ }
342
+ sourceBuffer.remove(start, end)
343
+ await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve, { once: true }))
344
+ // 校验清理结果,确保无残留
345
+ if (sourceBuffer.buffered.length === 0) {
346
+ console.log(`缓冲清理成功: ${start.toFixed(1)}s -> ${end.toFixed(1)}s | 无残留`)
347
+ return true
348
+ }
349
+ } catch (err) {
350
+ if (err.name === 'InvalidStateError' && i < retries - 1) {
351
+ console.warn(`缓冲清理重试 ${i + 1}/${retries}:`, err)
352
+ await new Promise(resolve => setTimeout(resolve, delay))
353
+ } else {
354
+ console.error('缓冲清理最终失败:', err)
355
+ // 兜底:强制清空所有缓冲
356
+ try {
357
+ sourceBuffer.remove(0, sourceBuffer.buffered.end(0))
358
+ } catch (e) {}
359
+ return false
360
+ }
361
+ }
362
+ }
363
+ return false
364
+ }
365
+
366
+ // 新增:获取当前缓冲范围 [start, end],简化代码
367
+ getBufferedRange() {
368
+ if (!this.sourceBuffer || this.sourceBuffer.buffered.length === 0) return [0, 0]
369
+ return [
370
+ this.sourceBuffer.buffered.start(0),
371
+ this.sourceBuffer.buffered.end(0)
372
+ ]
373
+ }
374
+
375
+ // 重写:适配逻辑仅在缓冲覆盖目标时间后生效,不提前适配到分片起始
376
+ getNearestValidPlayTime(targetTime) {
377
+ if (!this.sourceBuffer || this.sourceBuffer.buffered.length === 0) {
378
+ console.log('[适配位置] 无缓冲,使用目标时间:', targetTime)
379
+ return targetTime
380
+ }
381
+
382
+ const [bufferStart, bufferEnd] = this.getBufferedRange()
383
+ console.log(`[适配位置] 目标时间:${targetTime.toFixed(1)}s | 缓冲范围:${bufferStart.toFixed(1)}~${bufferEnd.toFixed(1)}s`)
384
+
385
+ // 核心修改:如果缓冲未覆盖目标时间,返回目标时间(等待加载),而非跳转到缓冲边界
386
+ if (targetTime > bufferEnd) {
387
+ console.log('[适配位置] 缓冲未覆盖目标时间,等待加载后再定位')
388
+ return targetTime
389
+ }
390
+ if (targetTime < bufferStart) return bufferStart
391
+ return targetTime
392
+ }
393
+
394
+ async autoAdaptBufferPosition() {
395
+ if (!this.$audio || !this.sourceBuffer || this.isSeeking) return
396
+ const targetTime = this.lastSeekTarget || this.$audio.currentTime
397
+ const newTime = this.getNearestValidPlayTime(targetTime)
398
+
399
+ if (newTime !== this.$audio.currentTime) {
400
+ console.log('[自动适配] 调整播放时间为:', newTime.toFixed(1))
401
+ this.$audio.currentTime = newTime
402
+ }
403
+ }
404
+
405
+ // 优化:加载后返回实际缓冲范围,校验是否加载到目标位置
406
+ async forcePreload(minBufferSeconds = 10) {
407
+ if (this.isPreloading || !this.sourceBuffer || !this.iterator) return [0, 0]
408
+ this.isPreloading = true
409
+ let preloaded = 0
410
+
411
+ try {
412
+ while (preloaded < minBufferSeconds) {
413
+ const { value: segment, done } = this.iterator.next()
414
+ if (done || !segment) break
415
+ await this.appendBufferSafe(this.sourceBuffer, segment)
416
+ preloaded++
417
+ }
418
+ const [start, end] = this.getBufferedRange()
419
+ console.log(`预加载完成,新增${preloaded}秒缓冲 | 当前缓冲:${start.toFixed(1)}~${end.toFixed(1)}s`)
420
+ return [start, end]
421
+ } catch (err) {
422
+ console.error('强制预加载失败:', err)
423
+ return [0, 0]
424
+ } finally {
425
+ this.isPreloading = false
426
+ }
427
+ }
428
+
429
+ /**
430
+ * 核心重写:解决定位到分片起始、向后跳转无反应、适配过早问题
431
+ */
432
+ async seekToTime(targetTime, isBackwardSeek = false) {
433
+ if (this.isSeeking) {
434
+ console.log('[seekToTime] 正在执行拖拽,跳过本次请求')
435
+ return
436
+ }
437
+ this.isSeeking = true
438
+ // 锁定最终目标时间,全程不改变
439
+ const finalTargetTime = Math.max(0, Math.min(targetTime, this.estimatedDuration))
440
+ this.lastSeekTarget = finalTargetTime
441
+ console.log(`[seekToTime] 锁定目标时间:${finalTargetTime.toFixed(1)}s | 向后跳转:${isBackwardSeek}`)
442
+
443
+ try {
444
+ // 1. 等待空闲 + 彻底清理旧缓冲
445
+ if (this.sourceBuffer.updating) {
446
+ await new Promise(resolve => this.sourceBuffer.addEventListener('updateend', resolve, { once: true }))
447
+ }
448
+ const [oldBufferStart, oldBufferEnd] = this.getBufferedRange()
449
+ if (oldBufferEnd > 0) {
450
+ await this.safeRemoveBuffer(this.sourceBuffer, oldBufferStart, oldBufferEnd)
451
+ }
452
+
453
+ // 2. 精准计算字节位置(使用可配置码率),重置迭代器
454
+ const targetBytePosition = Math.max(0, (finalTargetTime / this.estimatedDuration) * this.audioData.length)
455
+ this.iterator = this.wrapper.iterator(this.audioData.slice(targetBytePosition))
456
+ console.log(`[seekToTime] 迭代器定位到字节:${targetBytePosition} | 对应目标时间:${finalTargetTime.toFixed(1)}s`)
457
+
458
+ // 3. 预加载目标缓冲,等待加载完成
459
+ const [bufferStart, bufferEnd] = await this.forcePreload(20) // 增加预加载时长,确保覆盖目标时间
460
+
461
+ // 4. 适配位置(此时缓冲已加载,不会跳转到分片起始)
462
+ const adaptTime = this.getNearestValidPlayTime(finalTargetTime)
463
+ console.log(`[seekToTime] 缓冲加载完成 | 最终定位时间:${adaptTime.toFixed(1)}s`)
464
+
465
+ // 5. 强制设置播放位置,解决向后跳转无反应
466
+ this.$audio.currentTime = adaptTime
467
+ if (!this.isPlaying) {
468
+ await this.$audio.play()
469
+ this.isPlaying = true
470
+ }
471
+
472
+ } catch (err) {
473
+ console.error('定位失败:', err)
474
+ } finally {
475
+ // 延迟释放锁,确保缓冲完全加载
476
+ setTimeout(() => {
477
+ this.isSeeking = false
478
+ }, 500)
479
+ }
480
+ }
481
+
482
+ // 优化:使用可配置码率计算时长,支持校准
483
+ calculateEstimatedDuration(fileSizeBytes) {
484
+ const bitrateKbps = this.options.bitrateKbps
485
+ const fileSizeBits = fileSizeBytes * 8
486
+ return fileSizeBits / (bitrateKbps * 1000)
487
+ }
488
+
489
+ async appendBufferSafe(sourceBuffer, buffer) {
490
+ if (!sourceBuffer) return
491
+ if (sourceBuffer.updating) {
492
+ await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve, { once: true }))
493
+ }
494
+
495
+ try {
496
+ sourceBuffer.appendBuffer(buffer)
497
+ await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve, { once: true }))
498
+ } catch (err) {
499
+ if (err.name === 'QuotaExceededError') {
500
+ console.warn('缓冲区已满,清理最旧的10秒缓冲...')
501
+ await this.safeRemoveBuffer(sourceBuffer, 0, Math.min(10, sourceBuffer.buffered.end(0)))
502
+ sourceBuffer.appendBuffer(buffer)
503
+ await new Promise(resolve => sourceBuffer.addEventListener('updateend', resolve, { once: true }))
504
+ } else {
505
+ console.error('追加缓冲失败:', err)
506
+ }
507
+ }
508
+ }
509
+
510
+ async togglePlayPause() {
511
+ if (!this.$audio) return
512
+ if (this.isPlaying) {
513
+ this.$audio.pause()
514
+ this.isPlaying = false
515
+ } else {
516
+ const targetTime = this.lastSeekTarget || this.$audio.currentTime
517
+ const newTime = this.getNearestValidPlayTime(targetTime)
518
+ this.$audio.currentTime = newTime
519
+ await this.$audio.play()
520
+ this.isPlaying = true
521
+ }
522
+ }
523
+
524
+ clearMediaResources() {
525
+ if (this.$audio) {
526
+ this.$audio.pause()
527
+ this.$audio.removeAttribute('src')
528
+ }
529
+ if (this.currentMediaSource) {
530
+ try {
531
+ if (this.currentMediaSource.readyState !== 'closed') {
532
+ this.currentMediaSource.endOfStream()
533
+ }
534
+ } catch (e) {}
535
+ this.currentMediaSource = null
536
+ }
537
+ if (this.currentObjectUrl) {
538
+ URL.revokeObjectURL(this.currentObjectUrl)
539
+ this.currentObjectUrl = null
540
+ }
541
+ if (this.bufferCleaner) {
542
+ clearInterval(this.bufferCleaner)
543
+ this.bufferCleaner = null
544
+ }
545
+
546
+ this.isPlaying = false
547
+ this.sourceBuffer = null
548
+ this.iterator = null
549
+ this.loadNextSegment = false
550
+ this.audioData = null
551
+ this.wrapper = null
552
+ this.estimatedDuration = 0
553
+ this.isPreloading = false
554
+ this.lastSeekTarget = null
555
+ this.isSeeking = false
556
+ clearTimeout(this.seekDebounceTimer)
557
+ }
558
+
559
+ resume () {
560
+ console.log('aac不支持')
561
+ }
562
+
563
+ pause () {
564
+ console.log('aac不支持')
565
+ }
566
+
567
+ stop (callback) {
568
+ if (!this._play) {
569
+ callback?.()
570
+ return
571
+ }
572
+ this._play = false
573
+ this.$audio.pause()
574
+ this.$audio.currentTime = 0
575
+ this.$audio.dispatchEvent(new Event('stop'))
576
+ callback?.()
577
+ }
578
+
579
+ destroy() {
580
+ clearInterval(this._timer)
581
+ this.stop()
582
+ this.clearMediaResources()
583
+ }
584
+ }