@cloud-app-dev/vidc 4.0.20 → 4.0.22
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.
- package/es/AppContext/Sync.js +42 -0
- package/es/AppContext/index.js +141 -0
- package/es/AppContext/interface.d.ts +41 -0
- package/es/AppContext/static.js +9 -0
- package/es/Auth/index.js +14 -0
- package/es/AutoExit/index.js +19 -0
- package/es/CheckGroupFixed/demo.js +22 -0
- package/es/CheckGroupFixed/index.js +140 -0
- package/es/CheckGroupFixed/index.less +56 -0
- package/es/Config/index.js +77 -0
- package/es/Config/interface.d.ts +65 -0
- package/es/Config/utils.js +33 -0
- package/es/ConfigContext/index.js +21 -0
- package/es/CustomRenderSelect/index.js +72 -0
- package/es/CustomRenderSelect/index.less +25 -0
- package/es/DBTools/index.js +336 -0
- package/es/DisableMark/index.js +19 -0
- package/es/DisableMark/index.less +9 -0
- package/es/DomMove/demo.js +16 -0
- package/es/DomMove/index.js +139 -0
- package/es/DomMove/utils.js +32 -0
- package/es/Drag/DragAndDropItem.js +133 -0
- package/es/Drag/DropItem.js +50 -0
- package/es/Drag/index.d.ts +9 -0
- package/es/Drag/index.js +7 -0
- package/es/Drag/interface.d.ts +16 -0
- package/es/DynamicGridList/Demo.js +77 -0
- package/es/DynamicGridList/index.js +67 -0
- package/es/DynamicList/demo.js +44 -0
- package/es/DynamicList/index.js +86 -0
- package/es/DynamicList/index.less +17 -0
- package/es/DynamicList/interface.d.ts +19 -0
- package/es/DynamicList/utils.js +6 -0
- package/es/ErrorFallback/index.js +31 -0
- package/es/ErrorFallback/inerface.d.ts +48 -0
- package/es/EventTools/index.js +12 -0
- package/es/FrontendPlayer/index.js +2 -0
- package/es/FullScreen/index.js +33 -0
- package/es/FullScreen/index.less +18 -0
- package/es/GridList/Demo.js +80 -0
- package/es/GridList/data.js +609 -0
- package/es/GridList/hook.js +270 -0
- package/es/GridList/index.js +44 -0
- package/es/GridList/index.less +8 -0
- package/es/GridList/interface.d.ts +59 -0
- package/es/GridList/utils.js +42 -0
- package/es/HightLevel/index.js +18 -0
- package/es/HightLevel/index.less +3 -0
- package/es/IconFont/index.js +54 -0
- package/es/ImageView/index.js +51 -0
- package/es/ImageView/index.less +11 -0
- package/es/InstanceHistory/index.js +7 -0
- package/es/LabelPlayer/111.png +0 -0
- package/es/LabelPlayer/demo.js +115 -0
- package/es/LabelPlayer/index.js +160 -0
- package/es/LabelPlayer/index.less +24 -0
- package/es/LabelValue/index.js +27 -0
- package/es/LabelValue/index.less +23 -0
- package/es/List/demo.js +23 -0
- package/es/List/index.js +28 -0
- package/es/List/index.less +20 -0
- package/es/ListWithSizeAnimate/demo.js +98 -0
- package/es/ListWithSizeAnimate/index.js +85 -0
- package/es/ListWithSizeAnimate/index.less +23 -0
- package/es/LoaderScript/index.js +34 -0
- package/es/LoaderScript/utils.js +179 -0
- package/es/Map/AMap.d.ts +7109 -0
- package/es/Map/BasicMap/AMapInstance.js +98 -0
- package/es/Map/BasicMap/LeafletInstance.js +111 -0
- package/es/Map/BasicMap/index.js +90 -0
- package/es/Map/BasicMap/index.less +29 -0
- package/es/Map/ClusterLayer/demo.js +18 -0
- package/es/Map/ClusterLayer/hook.js +123 -0
- package/es/Map/ClusterLayer/index.js +28 -0
- package/es/Map/ClusterLayer/index.less +29 -0
- package/es/Map/ClusterLayer/props.d.ts +8 -0
- package/es/Map/Config/index.js +48 -0
- package/es/Map/Config/utils.js +65 -0
- package/es/Map/Context/index.js +51 -0
- package/es/Map/FindPio/index.js +13 -0
- package/es/Map/FindPio/index.less +7 -0
- package/es/Map/InfoWindow/MakerLikeWindow.js +108 -0
- package/es/Map/InfoWindow/demo.js +70 -0
- package/es/Map/InfoWindow/index.js +62 -0
- package/es/Map/LevelCenter/DragMarker/index.js +42 -0
- package/es/Map/LevelCenter/demo.js +38 -0
- package/es/Map/LevelCenter/index.js +66 -0
- package/es/Map/LoaderMap/index.js +62 -0
- package/es/Map/MapDrawSelect/demo.js +71 -0
- package/es/Map/MapDrawSelect/index.js +56 -0
- package/es/Map/MouseTool/index.js +40 -0
- package/es/Map/MouseTool/useMouseTools.js +83 -0
- package/es/Map/ResetTools/index.js +57 -0
- package/es/Map/ResetTools/index.less +39 -0
- package/es/Map/SinglePoint/demo.js +14 -0
- package/es/Map/SinglePoint/index.js +52 -0
- package/es/Map/SinglePoint/index.less +41 -0
- package/es/Map/hook/useMapEvent.js +19 -0
- package/es/Map/hook/useMapType.js +12 -0
- package/es/Map/icon.js +10 -0
- package/es/Map/index.js +25 -0
- package/es/Map/interface.d.ts +74 -0
- package/es/Map/points.js +1 -0
- package/es/Map/useMarker/index.js +71 -0
- package/es/Map/withMap/index.js +10 -0
- package/es/Picture/component/DefaultRects/RectInfo.js +80 -0
- package/es/Picture/component/DefaultRects/index.js +52 -0
- package/es/Picture/component/DefaultRects/index.less +211 -0
- package/es/Picture/component/DefaultRects/utils.js +11 -0
- package/es/Picture/component/DrawRect/index.js +46 -0
- package/es/Picture/component/DrawRect/index.less +8 -0
- package/es/Picture/component/RectMenu/index.js +76 -0
- package/es/Picture/component/RectMenu/index.less +36 -0
- package/es/Picture/component/RectMenu/utils.js +19 -0
- package/es/Picture/component/Tools/index.js +73 -0
- package/es/Picture/component/Tools/index.less +49 -0
- package/es/Picture/component/WheelScale/index.js +27 -0
- package/es/Picture/demo.js +105 -0
- package/es/Picture/index.js +341 -0
- package/es/Picture/index.less +20 -0
- package/es/Picture/interface.d.ts +196 -0
- package/es/Picture/loadCaptureRectImage.js +99 -0
- package/es/Picture/useDraw.js +103 -0
- package/es/Picture/utils.js +143 -0
- package/es/Player/api/index.js +309 -0
- package/es/Player/context.js +24 -0
- package/es/Player/contraller_bar/bar.js +20 -0
- package/es/Player/contraller_bar/contraller_event.js +48 -0
- package/es/Player/contraller_bar/index.js +27 -0
- package/es/Player/contraller_bar/left_bar.js +83 -0
- package/es/Player/contraller_bar/right_bar.js +32 -0
- package/es/Player/contraller_bar/time.js +19 -0
- package/es/Player/contraller_bar/useBarStatus.js +43 -0
- package/es/Player/contraller_bar/volume.js +62 -0
- package/es/Player/demo.js +266 -0
- package/es/Player/empty.js +4 -0
- package/es/Player/event/errorEvent.js +88 -0
- package/es/Player/event/eventName.js +29 -0
- package/es/Player/event/index.js +205 -0
- package/es/Player/fps_play.js +83 -0
- package/es/Player/frontend_player.js +64 -0
- package/es/Player/frontend_timeline.js +132 -0
- package/es/Player/iconfont.js +16 -0
- package/es/Player/index.js +2 -0
- package/es/Player/live_heart.js +45 -0
- package/es/Player/message.js +133 -0
- package/es/Player/player.d.ts +233 -0
- package/es/Player/segment_player.js +228 -0
- package/es/Player/segment_timeline.js +173 -0
- package/es/Player/single_player.js +262 -0
- package/es/Player/style/bar.less +43 -0
- package/es/Player/style/iconfont.js +43 -0
- package/es/Player/style/index.less +34 -0
- package/es/Player/style/message.less +56 -0
- package/es/Player/style/slider.less +106 -0
- package/es/Player/style/timeline.less +117 -0
- package/es/Player/style/volume.less +24 -0
- package/es/Player/timeline.js +95 -0
- package/es/Player/util.js +189 -0
- package/es/PlayerExt/demo.js +154 -0
- package/es/PlayerExt/index.js +188 -0
- package/es/PlayerExt/index.less +10 -0
- package/es/Progress/index.d.ts +9 -0
- package/es/Progress/index.js +53 -0
- package/es/Progress/index.less +21 -0
- package/es/ROI/demo.js +16 -0
- package/es/ROI/index.js +54 -0
- package/es/ROI/index.less +33 -0
- package/es/RefDrawer/Footer.js +22 -0
- package/es/RefDrawer/demo.js +18 -0
- package/es/RefDrawer/index.js +71 -0
- package/es/RefModal/demo.js +18 -0
- package/es/RefModal/index.js +70 -0
- package/es/ScreenPlayer/Live.js +212 -0
- package/es/ScreenPlayer/LiveTools.js +151 -0
- package/es/ScreenPlayer/PlayerWithExt.js +231 -0
- package/es/ScreenPlayer/RatePick.js +29 -0
- package/es/ScreenPlayer/Record.js +442 -0
- package/es/ScreenPlayer/RecordTools.js +169 -0
- package/es/ScreenPlayer/ScreenSelect.js +46 -0
- package/es/ScreenPlayer/SegmentTimeLine.js +36 -0
- package/es/ScreenPlayer/TimeMode.js +26 -0
- package/es/ScreenPlayer/TimeSelect.js +88 -0
- package/es/ScreenPlayer/demo.js +21 -0
- package/es/ScreenPlayer/demo2.js +194 -0
- package/es/ScreenPlayer/index.js +9 -0
- package/es/ScreenPlayer/index.less +335 -0
- package/es/ScreenPlayer/interface.d.ts +216 -0
- package/es/ScreenPlayer/useTimeSlider.js +456 -0
- package/es/ScreenPlayer/useVideoFit.js +35 -0
- package/es/ScreenPlayer/utils.js +85 -0
- package/es/SegmentPlayer/index.js +2 -0
- package/es/Service/http.js +133 -0
- package/es/Service/index.js +11 -0
- package/es/Service/interface.d.ts +23 -0
- package/es/Service/middleware.js +22 -0
- package/es/SocketEmitter/eventEmitter.js +88 -0
- package/es/SocketEmitter/index.js +125 -0
- package/es/SocketEmitter/interface.d.ts +4 -0
- package/es/TableLayout/index.js +27 -0
- package/es/TableLayout/index.less +4 -0
- package/es/ThemeAntd/demo.js +81 -0
- package/es/ThemeAntd/demo.less +20 -0
- package/es/ThemeAntd/index.js +21 -0
- package/es/ThemeAntd/index.less +4 -0
- package/es/Timeout/index.js +65 -0
- package/es/bigNumberTransformCN/index.js +58 -0
- package/es/cache/index.js +94 -0
- package/es/copy/index.js +9 -0
- package/es/core.d.ts +0 -0
- package/es/getThemeStyle/index.js +5 -0
- package/es/index.js +62 -0
- package/es/likeGo/index.js +31 -0
- package/es/likeGoSync/index.js +10 -0
- package/es/logger/index.js +30 -0
- package/es/nextTick/index.js +3 -0
- package/es/recorder/demo.js +181 -0
- package/es/recorder/index.js +992 -0
- package/es/submidstr/index.js +14 -0
- package/es/treeHelper/index.js +188 -0
- package/es/typings.d.ts +2 -0
- package/es/useDrawROI/index.js +318 -0
- package/es/useEventEmitterHandle/index.js +17 -0
- package/es/useFullscreen/demo.js +43 -0
- package/es/useFullscreen/index.js +76 -0
- package/es/useHistory/index.js +9 -0
- package/es/useHistory/interface.d.ts +3 -0
- package/es/useInfiniteScroll/index.js +102 -0
- package/es/useRafInterval/index.js +70 -0
- package/es/useSimpleState/index.js +35 -0
- package/es/useVirtualList/index.js +136 -0
- package/es/utils.js +46 -0
- package/es/uuid/index.js +19 -0
- package/package.json +2 -3
|
@@ -0,0 +1,992 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
3
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
4
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
5
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
6
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
7
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
8
|
+
function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
|
|
9
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
10
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
11
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
12
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
13
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
14
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
15
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
16
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
17
|
+
// 构造函数参数格式
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 在data中的offset位置开始写入str字符串
|
|
21
|
+
* @param {TypedArrays} data 二进制数据
|
|
22
|
+
* @param {Number} offset 偏移量
|
|
23
|
+
* @param {String} str 字符串
|
|
24
|
+
*/
|
|
25
|
+
function writeString(data, offset, str) {
|
|
26
|
+
for (var i = 0; i < str.length; i++) {
|
|
27
|
+
data.setUint8(offset + i, str.charCodeAt(i));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function concatenate() {
|
|
31
|
+
var totalLen = 0;
|
|
32
|
+
for (var _len = arguments.length, arrays = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
33
|
+
arrays[_key] = arguments[_key];
|
|
34
|
+
}
|
|
35
|
+
for (var _i = 0, _arrays = arrays; _i < _arrays.length; _i++) {
|
|
36
|
+
var arr = _arrays[_i];
|
|
37
|
+
totalLen += arr.byteLength;
|
|
38
|
+
}
|
|
39
|
+
var res = new Uint8Array(totalLen);
|
|
40
|
+
var offset = 0;
|
|
41
|
+
for (var _i2 = 0, _arrays2 = arrays; _i2 < _arrays2.length; _i2++) {
|
|
42
|
+
var _arr = _arrays2[_i2];
|
|
43
|
+
var uint8Arr = new Uint8Array(_arr);
|
|
44
|
+
res.set(uint8Arr, offset);
|
|
45
|
+
offset += _arr.byteLength;
|
|
46
|
+
}
|
|
47
|
+
return res.buffer;
|
|
48
|
+
}
|
|
49
|
+
var Recorder = /*#__PURE__*/function () {
|
|
50
|
+
/**
|
|
51
|
+
* @param {Object} options 包含以下三个参数:
|
|
52
|
+
* sampleBits,采样位数,一般8,16,默认16
|
|
53
|
+
* sampleRate,采样率,一般 11025、16000、22050、24000、44100、48000,默认为浏览器自带的采样率
|
|
54
|
+
* numChannels,声道,1或2
|
|
55
|
+
*/
|
|
56
|
+
function Recorder() {
|
|
57
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
58
|
+
_classCallCheck(this, Recorder);
|
|
59
|
+
_defineProperty(this, "isrecording", false);
|
|
60
|
+
// 是否正在录音
|
|
61
|
+
_defineProperty(this, "isplaying", false);
|
|
62
|
+
// 是否正在播放
|
|
63
|
+
_defineProperty(this, "ispause", false);
|
|
64
|
+
// 是否是暂停
|
|
65
|
+
_defineProperty(this, "context", void 0);
|
|
66
|
+
_defineProperty(this, "config", void 0);
|
|
67
|
+
// 配置
|
|
68
|
+
_defineProperty(this, "size", 0);
|
|
69
|
+
// 录音文件总长度
|
|
70
|
+
_defineProperty(this, "lBuffer", []);
|
|
71
|
+
// pcm音频数据搜集器(左声道)
|
|
72
|
+
_defineProperty(this, "rBuffer", []);
|
|
73
|
+
// pcm音频数据搜集器(右声道)
|
|
74
|
+
_defineProperty(this, "PCM", void 0);
|
|
75
|
+
// 最终的PCM数据缓存,避免多次encode
|
|
76
|
+
_defineProperty(this, "tempPCM", []);
|
|
77
|
+
// 边录边转时临时存放pcm的
|
|
78
|
+
_defineProperty(this, "audioInput", void 0);
|
|
79
|
+
_defineProperty(this, "inputSampleRate", void 0);
|
|
80
|
+
// 输入采样率
|
|
81
|
+
_defineProperty(this, "source", void 0);
|
|
82
|
+
// 音频输入
|
|
83
|
+
_defineProperty(this, "recorder", void 0);
|
|
84
|
+
_defineProperty(this, "outputSampleRate", 16000);
|
|
85
|
+
// 输出采样率
|
|
86
|
+
_defineProperty(this, "oututSampleBits", 16);
|
|
87
|
+
// 输出采样位数
|
|
88
|
+
_defineProperty(this, "analyser", void 0);
|
|
89
|
+
_defineProperty(this, "littleEdian", void 0);
|
|
90
|
+
// 是否是小端字节序
|
|
91
|
+
_defineProperty(this, "prevDomainData", void 0);
|
|
92
|
+
// 存放前一次图形化的数据
|
|
93
|
+
_defineProperty(this, "playStamp", 0);
|
|
94
|
+
// 播放录音时 AudioContext 记录的时间戳
|
|
95
|
+
_defineProperty(this, "playTime", 0);
|
|
96
|
+
// 记录录音播放时长
|
|
97
|
+
_defineProperty(this, "totalPlayTime", 0);
|
|
98
|
+
// 音频播放总长度
|
|
99
|
+
_defineProperty(this, "offset", 0);
|
|
100
|
+
// 边录边转,记录外部的获取偏移位置
|
|
101
|
+
_defineProperty(this, "stream", void 0);
|
|
102
|
+
// 流
|
|
103
|
+
_defineProperty(this, "fileSize", 0);
|
|
104
|
+
// 录音大小,byte为单位
|
|
105
|
+
_defineProperty(this, "duration", 0);
|
|
106
|
+
// 录音时长
|
|
107
|
+
_defineProperty(this, "onprogress", void 0);
|
|
108
|
+
var sampleBits = options.sampleBits ? options.sampleBits : 16;
|
|
109
|
+
var sampleRate = options.sampleRate ? options.sampleRate : 16000;
|
|
110
|
+
var numChannels = options.numChannels ? options.numChannels : 1;
|
|
111
|
+
|
|
112
|
+
// 临时audioContext,为了获取输入采样率的
|
|
113
|
+
var context = new AudioContext();
|
|
114
|
+
this.inputSampleRate = context.sampleRate; // 获取当前输入的采样率
|
|
115
|
+
// 配置config,检查值是否有问题
|
|
116
|
+
this.config = {
|
|
117
|
+
// 采样数位 8, 16
|
|
118
|
+
sampleBits: ~[8, 16].indexOf(sampleBits) ? sampleBits : 16,
|
|
119
|
+
// 采样率
|
|
120
|
+
sampleRate: ~[8000, 11025, 16000, 22050, 24000, 44100, 48000].indexOf(sampleRate) ? sampleRate : this.inputSampleRate,
|
|
121
|
+
// 声道数,1或2
|
|
122
|
+
numChannels: ~[1, 2].indexOf(numChannels) ? numChannels : 1,
|
|
123
|
+
// 是否需要边录边转,默认关闭,后期使用web worker
|
|
124
|
+
compiling: !!options.compiling || false
|
|
125
|
+
};
|
|
126
|
+
// 设置采样的参数
|
|
127
|
+
this.outputSampleRate = this.config.sampleRate; // 输出采样率
|
|
128
|
+
this.oututSampleBits = this.config.sampleBits; // 输出采样数位 8, 16
|
|
129
|
+
// 判断端字节序
|
|
130
|
+
this.littleEdian = function () {
|
|
131
|
+
var buffer = new ArrayBuffer(2);
|
|
132
|
+
new DataView(buffer).setInt16(0, 256, true);
|
|
133
|
+
return new Int16Array(buffer)[0] === 256;
|
|
134
|
+
}();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 初始化录音实例
|
|
139
|
+
*/
|
|
140
|
+
_createClass(Recorder, [{
|
|
141
|
+
key: "initRecorder",
|
|
142
|
+
value: function initRecorder() {
|
|
143
|
+
var _this = this;
|
|
144
|
+
if (this.context) {
|
|
145
|
+
// 关闭先前的录音实例,因为前次的实例会缓存少量前次的录音数据
|
|
146
|
+
this.destroy();
|
|
147
|
+
}
|
|
148
|
+
this.context = new AudioContext();
|
|
149
|
+
this.analyser = this.context.createAnalyser(); // 录音分析节点
|
|
150
|
+
this.analyser.fftSize = 2048; // 表示存储频域的大小
|
|
151
|
+
|
|
152
|
+
// 第一个参数表示收集采样的大小,采集完这么多后会触发 onaudioprocess 接口一次,该值一般为1024,2048,4096等,一般就设置为4096
|
|
153
|
+
// 第二,三个参数分别是输入的声道数和输出的声道数,保持一致即可。
|
|
154
|
+
this.recorder = this.context.createScriptProcessor(4096, this.config.numChannels, this.config.numChannels);
|
|
155
|
+
|
|
156
|
+
// 音频采集
|
|
157
|
+
this.recorder.onaudioprocess = function (e) {
|
|
158
|
+
var _this$onprogress;
|
|
159
|
+
if (!_this.isrecording || _this.ispause) {
|
|
160
|
+
// 不在录音时不需要处理,FF 在停止录音后,仍会触发 audioprocess 事件
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
// 左声道数据
|
|
164
|
+
// getChannelData返回Float32Array类型的pcm数据
|
|
165
|
+
var lData = e.inputBuffer.getChannelData(0),
|
|
166
|
+
rData = null,
|
|
167
|
+
vol = 0; // 音量百分比
|
|
168
|
+
|
|
169
|
+
_this.lBuffer.push(new Float32Array(lData));
|
|
170
|
+
_this.size += lData.length;
|
|
171
|
+
|
|
172
|
+
// 判断是否有右声道数据
|
|
173
|
+
if (2 === _this.config.numChannels) {
|
|
174
|
+
rData = e.inputBuffer.getChannelData(1);
|
|
175
|
+
_this.rBuffer.push(new Float32Array(rData));
|
|
176
|
+
_this.size += rData.length;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 边录边转处理
|
|
180
|
+
if (_this.config.compiling) {
|
|
181
|
+
var pcm = _this.transformIntoPCM(lData, rData);
|
|
182
|
+
_this.tempPCM.push(pcm);
|
|
183
|
+
// 计算录音大小
|
|
184
|
+
_this.fileSize = pcm.byteLength * _this.tempPCM.length;
|
|
185
|
+
} else {
|
|
186
|
+
// 计算录音大小
|
|
187
|
+
_this.fileSize = Math.floor(_this.size / Math.max(_this.inputSampleRate / _this.outputSampleRate, 1)) * (_this.oututSampleBits / 8);
|
|
188
|
+
}
|
|
189
|
+
// 为何此处计算大小需要分开计算。原因是先录后转时,是将所有数据一起处理,边录边转是单个 4096 处理,
|
|
190
|
+
// 有小数位的偏差。
|
|
191
|
+
|
|
192
|
+
// 计算音量百分比
|
|
193
|
+
vol = Math.max.apply(Math, lData) * 100;
|
|
194
|
+
// 统计录音时长
|
|
195
|
+
_this.duration += 4096 / _this.inputSampleRate;
|
|
196
|
+
// 录音时长回调
|
|
197
|
+
// 录音时长及响度回调
|
|
198
|
+
|
|
199
|
+
(_this$onprogress = _this.onprogress) === null || _this$onprogress === void 0 || _this$onprogress.call(_this, {
|
|
200
|
+
duration: _this.duration,
|
|
201
|
+
fileSize: _this.fileSize,
|
|
202
|
+
vol: vol,
|
|
203
|
+
data: _this.tempPCM // 当前所有的pcm数据,调用者控制增量
|
|
204
|
+
});
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* 开始录音
|
|
210
|
+
*
|
|
211
|
+
* @returns {Promise<{}>}
|
|
212
|
+
* @memberof Recorder
|
|
213
|
+
*/
|
|
214
|
+
}, {
|
|
215
|
+
key: "start",
|
|
216
|
+
value: (function () {
|
|
217
|
+
var _start = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
218
|
+
var _this$context, _this$audioInput, _this$analyser, _this$recorder, _this$context2;
|
|
219
|
+
var stream;
|
|
220
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
221
|
+
while (1) switch (_context.prev = _context.next) {
|
|
222
|
+
case 0:
|
|
223
|
+
if (navigator.mediaDevices) {
|
|
224
|
+
_context.next = 2;
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
return _context.abrupt("return", Promise.reject(new Error('浏览器不支持 navigator.mediaDevices !')));
|
|
228
|
+
case 2:
|
|
229
|
+
if (!this.isrecording) {
|
|
230
|
+
_context.next = 4;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
return _context.abrupt("return", Promise.resolve());
|
|
234
|
+
case 4:
|
|
235
|
+
// 清空数据
|
|
236
|
+
this.clear();
|
|
237
|
+
this.initRecorder();
|
|
238
|
+
this.isrecording = true;
|
|
239
|
+
_context.next = 9;
|
|
240
|
+
return navigator.mediaDevices.getUserMedia({
|
|
241
|
+
audio: true
|
|
242
|
+
});
|
|
243
|
+
case 9:
|
|
244
|
+
stream = _context.sent;
|
|
245
|
+
// audioInput表示音频源节点
|
|
246
|
+
// stream是通过navigator.getUserMedia获取的外部(如麦克风)stream音频输出,对于这就是输入
|
|
247
|
+
this.audioInput = (_this$context = this.context) === null || _this$context === void 0 ? void 0 : _this$context.createMediaStreamSource(stream);
|
|
248
|
+
this.stream = stream;
|
|
249
|
+
// audioInput 为声音源,连接到处理节点 recorder
|
|
250
|
+
(_this$audioInput = this.audioInput) === null || _this$audioInput === void 0 || _this$audioInput.connect(this.analyser);
|
|
251
|
+
(_this$analyser = this.analyser) === null || _this$analyser === void 0 || _this$analyser.connect(this.recorder);
|
|
252
|
+
// 处理节点 recorder 连接到扬声器
|
|
253
|
+
(_this$recorder = this.recorder) === null || _this$recorder === void 0 || _this$recorder.connect((_this$context2 = this.context) === null || _this$context2 === void 0 ? void 0 : _this$context2.destination);
|
|
254
|
+
case 15:
|
|
255
|
+
case "end":
|
|
256
|
+
return _context.stop();
|
|
257
|
+
}
|
|
258
|
+
}, _callee, this);
|
|
259
|
+
}));
|
|
260
|
+
function start() {
|
|
261
|
+
return _start.apply(this, arguments);
|
|
262
|
+
}
|
|
263
|
+
return start;
|
|
264
|
+
}()
|
|
265
|
+
/**
|
|
266
|
+
* 暂停录音
|
|
267
|
+
*
|
|
268
|
+
* @memberof Recorder
|
|
269
|
+
*/
|
|
270
|
+
)
|
|
271
|
+
}, {
|
|
272
|
+
key: "pause",
|
|
273
|
+
value: function pause() {
|
|
274
|
+
if (this.isrecording && !this.ispause) {
|
|
275
|
+
this.ispause = true;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* 继续录音
|
|
281
|
+
*
|
|
282
|
+
* @memberof Recorder
|
|
283
|
+
*/
|
|
284
|
+
}, {
|
|
285
|
+
key: "resume",
|
|
286
|
+
value: function resume() {
|
|
287
|
+
if (this.isrecording && this.ispause) {
|
|
288
|
+
this.ispause = false;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* 停止录音
|
|
294
|
+
*
|
|
295
|
+
* @memberof Recorder
|
|
296
|
+
*/
|
|
297
|
+
}, {
|
|
298
|
+
key: "stop",
|
|
299
|
+
value: function stop() {
|
|
300
|
+
var _this$audioInput2, _this$recorder2;
|
|
301
|
+
this.isrecording = false;
|
|
302
|
+
(_this$audioInput2 = this.audioInput) === null || _this$audioInput2 === void 0 || _this$audioInput2.disconnect();
|
|
303
|
+
(_this$recorder2 = this.recorder) === null || _this$recorder2 === void 0 || _this$recorder2.disconnect();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* 播放录音
|
|
308
|
+
*
|
|
309
|
+
* @memberof Recorder
|
|
310
|
+
*/
|
|
311
|
+
}, {
|
|
312
|
+
key: "play",
|
|
313
|
+
value: function play() {
|
|
314
|
+
var _this$source;
|
|
315
|
+
this.stop();
|
|
316
|
+
// 关闭前一次音频播放
|
|
317
|
+
(_this$source = this.source) === null || _this$source === void 0 || _this$source.stop();
|
|
318
|
+
this.isplaying = true;
|
|
319
|
+
this.playTime = 0;
|
|
320
|
+
|
|
321
|
+
// 记录开始播放的时间
|
|
322
|
+
this.playAudioData();
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* 获取音频文件已经播放了的时间
|
|
327
|
+
*
|
|
328
|
+
* @returns {number}
|
|
329
|
+
* @memberof Recorder
|
|
330
|
+
*/
|
|
331
|
+
}, {
|
|
332
|
+
key: "getPlayTime",
|
|
333
|
+
value: function getPlayTime() {
|
|
334
|
+
var _now = 0;
|
|
335
|
+
if (this.isplaying) {
|
|
336
|
+
var _this$context$current, _this$context3;
|
|
337
|
+
// 播放中,使用预留时间 + 偏差时间
|
|
338
|
+
_now = ((_this$context$current = (_this$context3 = this.context) === null || _this$context3 === void 0 ? void 0 : _this$context3.currentTime) !== null && _this$context$current !== void 0 ? _this$context$current : 0) - this.playStamp + this.playTime;
|
|
339
|
+
} else {
|
|
340
|
+
_now = this.playTime;
|
|
341
|
+
}
|
|
342
|
+
if (_now >= this.totalPlayTime) {
|
|
343
|
+
_now = this.totalPlayTime;
|
|
344
|
+
}
|
|
345
|
+
return _now;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* 暂停播放录音
|
|
350
|
+
*
|
|
351
|
+
* @memberof Recorder
|
|
352
|
+
*/
|
|
353
|
+
}, {
|
|
354
|
+
key: "pausePlay",
|
|
355
|
+
value: function pausePlay() {
|
|
356
|
+
var _this$source2, _this$context$current2, _this$context4;
|
|
357
|
+
if (this.isrecording || !this.isplaying) {
|
|
358
|
+
// 正在录音或没有播放,暂停无效
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
(_this$source2 = this.source) === null || _this$source2 === void 0 || _this$source2.disconnect();
|
|
362
|
+
// 多次暂停需要累加
|
|
363
|
+
this.playTime += ((_this$context$current2 = (_this$context4 = this.context) === null || _this$context4 === void 0 ? void 0 : _this$context4.currentTime) !== null && _this$context$current2 !== void 0 ? _this$context$current2 : 0) - this.playStamp;
|
|
364
|
+
this.isplaying = false;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* 恢复播放录音
|
|
369
|
+
*
|
|
370
|
+
* @memberof Recorder
|
|
371
|
+
*/
|
|
372
|
+
}, {
|
|
373
|
+
key: "resumePlay",
|
|
374
|
+
value: function resumePlay() {
|
|
375
|
+
if (this.isrecording || this.isplaying || 0 === this.playTime) {
|
|
376
|
+
// 正在录音或已经播放或没开始播放,恢复无效
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
this.isplaying = true;
|
|
380
|
+
this.playAudioData();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* 停止播放
|
|
385
|
+
*
|
|
386
|
+
* @memberof Recorder
|
|
387
|
+
*/
|
|
388
|
+
}, {
|
|
389
|
+
key: "stopPlay",
|
|
390
|
+
value: function stopPlay() {
|
|
391
|
+
var _this$source3;
|
|
392
|
+
if (this.isrecording) {
|
|
393
|
+
// 正在录音,停止录音播放无效
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
this.playTime = 0;
|
|
397
|
+
this.isplaying = false;
|
|
398
|
+
(_this$source3 = this.source) === null || _this$source3 === void 0 || _this$source3.stop();
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* 获取当前已经录音的PCM音频数据
|
|
403
|
+
*
|
|
404
|
+
* @returns[DataView]
|
|
405
|
+
* @memberof Recorder
|
|
406
|
+
*/
|
|
407
|
+
}, {
|
|
408
|
+
key: "getWholeData",
|
|
409
|
+
value: function getWholeData() {
|
|
410
|
+
return this.tempPCM;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* 获取余下的新数据,不包括 getNextData 前一次获取的数据
|
|
415
|
+
*
|
|
416
|
+
* @returns [DataView]
|
|
417
|
+
* @memberof Recorder
|
|
418
|
+
*/
|
|
419
|
+
}, {
|
|
420
|
+
key: "getNextData",
|
|
421
|
+
value: function getNextData() {
|
|
422
|
+
var length = this.tempPCM.length,
|
|
423
|
+
data = this.tempPCM.slice(this.offset);
|
|
424
|
+
this.offset = length;
|
|
425
|
+
if (data.length === 0) {
|
|
426
|
+
return undefined;
|
|
427
|
+
}
|
|
428
|
+
return concatenate.apply(void 0, _toConsumableArray(data.map(function (v) {
|
|
429
|
+
return v.buffer;
|
|
430
|
+
})));
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* 利用 decodeAudioData播放录音数据,每次播放都需创建,因为buffersource只能被使用一次
|
|
435
|
+
*
|
|
436
|
+
* @private
|
|
437
|
+
* @memberof Recorder
|
|
438
|
+
*/
|
|
439
|
+
}, {
|
|
440
|
+
key: "playAudioData",
|
|
441
|
+
value: function playAudioData() {
|
|
442
|
+
var _this$context5,
|
|
443
|
+
_this2 = this;
|
|
444
|
+
(_this$context5 = this.context) === null || _this$context5 === void 0 || _this$context5.decodeAudioData(this.getWAV().buffer, function (buffer) {
|
|
445
|
+
var _this2$context, _this2$analyser, _this2$context2, _this2$context3;
|
|
446
|
+
_this2.source = (_this2$context = _this2.context) === null || _this2$context === void 0 ? void 0 : _this2$context.createBufferSource();
|
|
447
|
+
|
|
448
|
+
// 设置数据
|
|
449
|
+
_this2.source.buffer = buffer;
|
|
450
|
+
_this2.totalPlayTime = _this2.source.buffer.duration;
|
|
451
|
+
// connect到分析器,还是用录音的,因为播放时不能录音的
|
|
452
|
+
_this2.source.connect(_this2.analyser);
|
|
453
|
+
(_this2$analyser = _this2.analyser) === null || _this2$analyser === void 0 || _this2$analyser.connect((_this2$context2 = _this2.context) === null || _this2$context2 === void 0 ? void 0 : _this2$context2.destination);
|
|
454
|
+
_this2.source.start(0, _this2.playTime);
|
|
455
|
+
|
|
456
|
+
// 记录当前的时间戳,以备暂停时使用
|
|
457
|
+
_this2.playStamp = (_this2$context3 = _this2.context) === null || _this2$context3 === void 0 ? void 0 : _this2$context3.currentTime;
|
|
458
|
+
}, function (e) {
|
|
459
|
+
Recorder.throwError(e);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* 获取当前录音的波形数据,
|
|
465
|
+
* 调取频率由外部控制。
|
|
466
|
+
*
|
|
467
|
+
* @memberof Recorder
|
|
468
|
+
*/
|
|
469
|
+
}, {
|
|
470
|
+
key: "getRecordAnalyseData",
|
|
471
|
+
value: function getRecordAnalyseData() {
|
|
472
|
+
var _this$analyser2, _this$analyser3;
|
|
473
|
+
if (this.ispause) {
|
|
474
|
+
// 暂停时不需要发送录音的数据,处理FF下暂停仍就获取录音数据的问题
|
|
475
|
+
// 为防止暂停后,画面空白,故返回先前的数据
|
|
476
|
+
return this.prevDomainData;
|
|
477
|
+
}
|
|
478
|
+
var dataArray = new Uint8Array((_this$analyser2 = this.analyser) === null || _this$analyser2 === void 0 ? void 0 : _this$analyser2.frequencyBinCount);
|
|
479
|
+
// 将数据拷贝到dataArray中。
|
|
480
|
+
(_this$analyser3 = this.analyser) === null || _this$analyser3 === void 0 || _this$analyser3.getByteTimeDomainData(dataArray);
|
|
481
|
+
return this.prevDomainData = dataArray;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* 获取录音播放时的波形数据,
|
|
486
|
+
*
|
|
487
|
+
* @memberof Recorder
|
|
488
|
+
*/
|
|
489
|
+
}, {
|
|
490
|
+
key: "getPlayAnalyseData",
|
|
491
|
+
value: function getPlayAnalyseData() {
|
|
492
|
+
// 现在录音和播放不允许同时进行,所有复用的录音的analyser节点。
|
|
493
|
+
return this.getRecordAnalyseData();
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* 获取PCM编码的二进制数据(dataview)
|
|
498
|
+
*
|
|
499
|
+
* @returns {dataview} PCM二进制数据
|
|
500
|
+
* @memberof Recorder
|
|
501
|
+
*/
|
|
502
|
+
}, {
|
|
503
|
+
key: "getPCM",
|
|
504
|
+
value: function getPCM() {
|
|
505
|
+
if (this.tempPCM.length) {
|
|
506
|
+
// 优先使用边录边存下的
|
|
507
|
+
// 将存下的 DataView 数据合并了
|
|
508
|
+
var buffer = new ArrayBuffer(this.tempPCM.length * this.tempPCM[0].byteLength),
|
|
509
|
+
pcm = new DataView(buffer),
|
|
510
|
+
offset = 0;
|
|
511
|
+
|
|
512
|
+
// 遍历存储数据
|
|
513
|
+
this.tempPCM.forEach(function (block) {
|
|
514
|
+
for (var i = 0, len = block.byteLength; i < len; ++i) {
|
|
515
|
+
pcm.setInt8(offset, block.getInt8(i));
|
|
516
|
+
offset++;
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
// 最终的PCM数据已经有了,temp不需要了
|
|
520
|
+
this.PCM = pcm;
|
|
521
|
+
this.tempPCM = [];
|
|
522
|
+
}
|
|
523
|
+
if (this.PCM) {
|
|
524
|
+
// 给缓存
|
|
525
|
+
return this.PCM;
|
|
526
|
+
}
|
|
527
|
+
// 二维转一维
|
|
528
|
+
var data = this.flat();
|
|
529
|
+
// 压缩或扩展
|
|
530
|
+
data = Recorder.compress(data, this.inputSampleRate, this.outputSampleRate);
|
|
531
|
+
// 按采样位数重新编码
|
|
532
|
+
this.PCM = Recorder.encodePCM(data, this.oututSampleBits, this.littleEdian);
|
|
533
|
+
return this.PCM;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* 获取PCM格式的blob数据
|
|
538
|
+
*
|
|
539
|
+
* @returns { blob } PCM格式的blob数据
|
|
540
|
+
* @memberof Recorder
|
|
541
|
+
*/
|
|
542
|
+
}, {
|
|
543
|
+
key: "getPCMBlob",
|
|
544
|
+
value: function getPCMBlob() {
|
|
545
|
+
// 先停止
|
|
546
|
+
this.stop();
|
|
547
|
+
return new Blob([this.getPCM()]);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* 下载录音pcm数据
|
|
552
|
+
*
|
|
553
|
+
* @param {string} [name='recorder'] 重命名的名字
|
|
554
|
+
* @memberof Recorder
|
|
555
|
+
*/
|
|
556
|
+
}, {
|
|
557
|
+
key: "downloadPCM",
|
|
558
|
+
value: function downloadPCM() {
|
|
559
|
+
var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'recorder';
|
|
560
|
+
var pcmBlob = this.getPCMBlob();
|
|
561
|
+
this.download(pcmBlob, name, 'pcm');
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* 获取WAV编码的二进制数据(dataview)
|
|
566
|
+
*
|
|
567
|
+
* @returns {dataview} WAV编码的二进制数据
|
|
568
|
+
* @memberof Recorder
|
|
569
|
+
*/
|
|
570
|
+
}, {
|
|
571
|
+
key: "getWAV",
|
|
572
|
+
value: function getWAV() {
|
|
573
|
+
var pcmTemp = this.getPCM(),
|
|
574
|
+
wavTemp = Recorder.encodeWAV(pcmTemp, this.inputSampleRate, this.outputSampleRate, this.config.numChannels, this.oututSampleBits, this.littleEdian);
|
|
575
|
+
return wavTemp;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* 获取WAV音频的blob数据
|
|
580
|
+
*
|
|
581
|
+
* @returns { Blob } wav格式blob数据
|
|
582
|
+
* @memberof Recorder
|
|
583
|
+
*/
|
|
584
|
+
}, {
|
|
585
|
+
key: "getWAVBlob",
|
|
586
|
+
value: function getWAVBlob() {
|
|
587
|
+
// 先停止
|
|
588
|
+
this.stop();
|
|
589
|
+
return new Blob([this.getWAV()], {
|
|
590
|
+
type: 'audio/wav'
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* 下载录音的wav数据
|
|
596
|
+
*
|
|
597
|
+
* @param {string} [name='recorder'] 重命名的名字
|
|
598
|
+
* @memberof Recorder
|
|
599
|
+
*/
|
|
600
|
+
}, {
|
|
601
|
+
key: "downloadWAV",
|
|
602
|
+
value: function downloadWAV() {
|
|
603
|
+
var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'recorder';
|
|
604
|
+
var wavBlob = this.getWAVBlob();
|
|
605
|
+
this.download(wavBlob, name, 'wav');
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* 将获取到到左右声道的Float32Array数据编码转化
|
|
610
|
+
*
|
|
611
|
+
* @param {Float32Array} lData 左声道数据
|
|
612
|
+
* @param {Float32Array} rData 有声道数据
|
|
613
|
+
* @returns DataView
|
|
614
|
+
*/
|
|
615
|
+
}, {
|
|
616
|
+
key: "transformIntoPCM",
|
|
617
|
+
value: function transformIntoPCM(lData, rData) {
|
|
618
|
+
var lBuffer = new Float32Array(lData);
|
|
619
|
+
var rBuffer = new Float32Array(rData);
|
|
620
|
+
var data = Recorder.compress({
|
|
621
|
+
left: lBuffer,
|
|
622
|
+
right: rBuffer
|
|
623
|
+
}, this.inputSampleRate, this.outputSampleRate);
|
|
624
|
+
return Recorder.encodePCM(data, this.oututSampleBits, this.littleEdian);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* 销毁录音对象
|
|
629
|
+
* @memberof Recorder
|
|
630
|
+
*/
|
|
631
|
+
}, {
|
|
632
|
+
key: "destroy",
|
|
633
|
+
value: function destroy() {
|
|
634
|
+
// 结束流
|
|
635
|
+
this.stopStream();
|
|
636
|
+
return this.closeAudioContext();
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* 终止流(这可以让浏览器上正在录音的标志消失掉)
|
|
641
|
+
* @private
|
|
642
|
+
* @memberof Recorder
|
|
643
|
+
*/
|
|
644
|
+
}, {
|
|
645
|
+
key: "stopStream",
|
|
646
|
+
value: function stopStream() {
|
|
647
|
+
if (this.stream && this.stream.getTracks) {
|
|
648
|
+
this.stream.getTracks().forEach(function (track) {
|
|
649
|
+
return track.stop();
|
|
650
|
+
});
|
|
651
|
+
this.stream = undefined;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* close兼容方案
|
|
657
|
+
* 如firefox 30 等低版本浏览器没有 close方法
|
|
658
|
+
*/
|
|
659
|
+
}, {
|
|
660
|
+
key: "closeAudioContext",
|
|
661
|
+
value: function closeAudioContext() {
|
|
662
|
+
if (this.context && this.context.state !== 'closed') {
|
|
663
|
+
return this.context.close();
|
|
664
|
+
} else {
|
|
665
|
+
return Promise.resolve();
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* 下载录音文件
|
|
671
|
+
* @private
|
|
672
|
+
* @param {*} blob blob数据
|
|
673
|
+
* @param {string} name 下载的文件名
|
|
674
|
+
* @param {string} type 下载的文件后缀
|
|
675
|
+
* @memberof Recorder
|
|
676
|
+
*/
|
|
677
|
+
}, {
|
|
678
|
+
key: "download",
|
|
679
|
+
value: function download(blob, name, type) {
|
|
680
|
+
try {
|
|
681
|
+
var oA = document.createElement('a');
|
|
682
|
+
oA.href = window.URL.createObjectURL(blob);
|
|
683
|
+
oA.download = name + '.' + type;
|
|
684
|
+
oA.click();
|
|
685
|
+
} catch (e) {
|
|
686
|
+
Recorder.throwError(e);
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* 清空状态,重新开始录音(变量初始化)
|
|
692
|
+
*
|
|
693
|
+
* @private
|
|
694
|
+
* @memberof Recorder
|
|
695
|
+
*/
|
|
696
|
+
}, {
|
|
697
|
+
key: "clear",
|
|
698
|
+
value: function clear() {
|
|
699
|
+
this.lBuffer.length = 0;
|
|
700
|
+
this.rBuffer.length = 0;
|
|
701
|
+
this.size = 0;
|
|
702
|
+
this.fileSize = 0;
|
|
703
|
+
this.PCM = null;
|
|
704
|
+
this.audioInput = undefined;
|
|
705
|
+
this.duration = 0;
|
|
706
|
+
this.ispause = false;
|
|
707
|
+
this.isplaying = false;
|
|
708
|
+
this.playTime = 0;
|
|
709
|
+
this.totalPlayTime = 0;
|
|
710
|
+
|
|
711
|
+
// 录音前,关闭录音播放
|
|
712
|
+
if (this.source) {
|
|
713
|
+
this.source.stop();
|
|
714
|
+
// 重新开启录制,由于新建了 AudioContext ,source需要清空,
|
|
715
|
+
// 处理iphone 上 safari 浏览器 第二次播放报错的问题。
|
|
716
|
+
this.source = undefined;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* 将二维数组转一维
|
|
722
|
+
*
|
|
723
|
+
* @private
|
|
724
|
+
* @returns {float32array} 音频pcm二进制数据
|
|
725
|
+
* @memberof Recorder
|
|
726
|
+
*/
|
|
727
|
+
}, {
|
|
728
|
+
key: "flat",
|
|
729
|
+
value: function flat() {
|
|
730
|
+
var lData = null,
|
|
731
|
+
rData = new Float32Array(0); // 右声道默认为0
|
|
732
|
+
|
|
733
|
+
// 创建存放数据的容器
|
|
734
|
+
if (1 === this.config.numChannels) {
|
|
735
|
+
lData = new Float32Array(this.size);
|
|
736
|
+
} else {
|
|
737
|
+
lData = new Float32Array(this.size / 2);
|
|
738
|
+
rData = new Float32Array(this.size / 2);
|
|
739
|
+
}
|
|
740
|
+
// 合并
|
|
741
|
+
var offset = 0; // 偏移量计算
|
|
742
|
+
|
|
743
|
+
// 将二维数据,转成一维数据
|
|
744
|
+
// 左声道
|
|
745
|
+
for (var i = 0; i < this.lBuffer.length; i++) {
|
|
746
|
+
lData.set(this.lBuffer[i], offset);
|
|
747
|
+
offset += this.lBuffer[i].length;
|
|
748
|
+
}
|
|
749
|
+
offset = 0;
|
|
750
|
+
// 右声道
|
|
751
|
+
for (var _i3 = 0; _i3 < this.rBuffer.length; _i3++) {
|
|
752
|
+
rData.set(this.rBuffer[_i3], offset);
|
|
753
|
+
offset += this.rBuffer[_i3].length;
|
|
754
|
+
}
|
|
755
|
+
return {
|
|
756
|
+
left: lData,
|
|
757
|
+
right: rData
|
|
758
|
+
};
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* 播放外部音乐文件
|
|
763
|
+
*
|
|
764
|
+
* @param {float32array} blob blob音频数据
|
|
765
|
+
* @memberof Recorder
|
|
766
|
+
*/
|
|
767
|
+
}], [{
|
|
768
|
+
key: "playAudio",
|
|
769
|
+
value: function playAudio(blob) {
|
|
770
|
+
var oAudio = document.createElement('audio');
|
|
771
|
+
oAudio.src = window.URL.createObjectURL(blob);
|
|
772
|
+
// 播放音乐
|
|
773
|
+
oAudio.play();
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* 数据合并压缩
|
|
778
|
+
* 根据输入和输出的采样率压缩数据,
|
|
779
|
+
* 比如输入的采样率是48k的,我们需要的是(输出)的是16k的,由于48k与16k是3倍关系,
|
|
780
|
+
* 所以输入数据中每隔3取1位
|
|
781
|
+
*
|
|
782
|
+
* @static
|
|
783
|
+
* @param {float32array} data [-1, 1]的pcm数据
|
|
784
|
+
* @param {number} inputSampleRate 输入采样率
|
|
785
|
+
* @param {number} outputSampleRate 输出采样率
|
|
786
|
+
* @returns {float32array} 压缩处理后的二进制数据
|
|
787
|
+
* @memberof Recorder
|
|
788
|
+
*/
|
|
789
|
+
}, {
|
|
790
|
+
key: "compress",
|
|
791
|
+
value: function compress(data, inputSampleRate, outputSampleRate) {
|
|
792
|
+
// 压缩,根据采样率进行压缩
|
|
793
|
+
var rate = inputSampleRate / outputSampleRate,
|
|
794
|
+
compression = Math.max(rate, 1),
|
|
795
|
+
lData = data.left,
|
|
796
|
+
rData = data.right,
|
|
797
|
+
length = Math.floor((lData.length + rData.length) / rate),
|
|
798
|
+
result = new Float32Array(length),
|
|
799
|
+
index = 0,
|
|
800
|
+
j = 0;
|
|
801
|
+
|
|
802
|
+
// 循环间隔 compression 位取一位数据
|
|
803
|
+
while (index < length) {
|
|
804
|
+
var temp = Math.floor(j);
|
|
805
|
+
result[index] = lData[temp];
|
|
806
|
+
index++;
|
|
807
|
+
if (rData.length) {
|
|
808
|
+
/*
|
|
809
|
+
* 双声道处理
|
|
810
|
+
* e.inputBuffer.getChannelData(0)得到了左声道4096个样本数据,1是右声道的数据,
|
|
811
|
+
* 此处需要组和成LRLRLR这种格式,才能正常播放,所以要处理下
|
|
812
|
+
*/
|
|
813
|
+
result[index] = rData[temp];
|
|
814
|
+
index++;
|
|
815
|
+
}
|
|
816
|
+
j += compression;
|
|
817
|
+
}
|
|
818
|
+
// 返回压缩后的一维数据
|
|
819
|
+
return result;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* 转换到我们需要的对应格式的编码
|
|
824
|
+
*
|
|
825
|
+
* @static
|
|
826
|
+
* @param {Float32Array} bytes pcm二进制数据
|
|
827
|
+
* @param {number} sampleBits 采样位数
|
|
828
|
+
* @param {boolean} littleEdian 是否是小端字节序
|
|
829
|
+
* @returns {dataview} pcm二进制数据
|
|
830
|
+
* @memberof Recorder
|
|
831
|
+
*/
|
|
832
|
+
}, {
|
|
833
|
+
key: "encodePCM",
|
|
834
|
+
value: function encodePCM(bytes, sampleBits) {
|
|
835
|
+
var littleEdian = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
836
|
+
var offset = 0,
|
|
837
|
+
dataLength = bytes.length * (sampleBits / 8),
|
|
838
|
+
buffer = new ArrayBuffer(dataLength),
|
|
839
|
+
data = new DataView(buffer);
|
|
840
|
+
|
|
841
|
+
// 写入采样数据
|
|
842
|
+
if (sampleBits === 8) {
|
|
843
|
+
for (var i = 0; i < bytes.length; i++, offset++) {
|
|
844
|
+
// 范围[-1, 1]
|
|
845
|
+
var s = Math.max(-1, Math.min(1, bytes[i]));
|
|
846
|
+
// 8位采样位划分成2^8=256份,它的范围是0-255;
|
|
847
|
+
// 对于8位的话,负数*128,正数*127,然后整体向上平移128(+128),即可得到[0,255]范围的数据。
|
|
848
|
+
var val = s < 0 ? s * 128 : s * 127;
|
|
849
|
+
val = +val + 128;
|
|
850
|
+
data.setInt8(offset, val);
|
|
851
|
+
}
|
|
852
|
+
} else {
|
|
853
|
+
for (var _i4 = 0; _i4 < bytes.length; _i4++, offset += 2) {
|
|
854
|
+
var _s = Math.max(-1, Math.min(1, bytes[_i4]));
|
|
855
|
+
// 16位的划分的是2^16=65536份,范围是-32768到32767
|
|
856
|
+
// 因为我们收集的数据范围在[-1,1],那么你想转换成16位的话,只需要对负数*32768,对正数*32767,即可得到范围在[-32768,32767]的数据。
|
|
857
|
+
data.setInt16(offset, _s < 0 ? _s * 0x8000 : _s * 0x7fff, littleEdian);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
return data;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* 编码wav,一般wav格式是在pcm文件前增加44个字节的文件头,
|
|
865
|
+
* 所以,此处只需要在pcm数据前增加下就行了。
|
|
866
|
+
*
|
|
867
|
+
* @static
|
|
868
|
+
* @param {DataView} bytes pcm二进制数据
|
|
869
|
+
* @param {number} inputSampleRate 输入采样率
|
|
870
|
+
* @param {number} outputSampleRate 输出采样率
|
|
871
|
+
* @param {number} numChannels 声道数
|
|
872
|
+
* @param {number} oututSampleBits 输出采样位数
|
|
873
|
+
* @param {boolean} littleEdian 是否是小端字节序
|
|
874
|
+
* @returns {DataView} wav二进制数据
|
|
875
|
+
* @memberof Recorder
|
|
876
|
+
*/
|
|
877
|
+
}, {
|
|
878
|
+
key: "encodeWAV",
|
|
879
|
+
value: function encodeWAV(bytes, inputSampleRate, outputSampleRate, numChannels, oututSampleBits) {
|
|
880
|
+
var littleEdian = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
|
|
881
|
+
var sampleRate = outputSampleRate > inputSampleRate ? inputSampleRate : outputSampleRate,
|
|
882
|
+
// 输出采样率较大时,仍使用输入的值,
|
|
883
|
+
sampleBits = oututSampleBits,
|
|
884
|
+
buffer = new ArrayBuffer(44 + bytes.byteLength),
|
|
885
|
+
data = new DataView(buffer),
|
|
886
|
+
channelCount = numChannels,
|
|
887
|
+
// 声道
|
|
888
|
+
offset = 0;
|
|
889
|
+
|
|
890
|
+
// 资源交换文件标识符
|
|
891
|
+
writeString(data, offset, 'RIFF');
|
|
892
|
+
offset += 4;
|
|
893
|
+
// 下个地址开始到文件尾总字节数,即文件大小-8
|
|
894
|
+
data.setUint32(offset, 36 + bytes.byteLength, littleEdian);
|
|
895
|
+
offset += 4;
|
|
896
|
+
// WAV文件标志
|
|
897
|
+
writeString(data, offset, 'WAVE');
|
|
898
|
+
offset += 4;
|
|
899
|
+
// 波形格式标志
|
|
900
|
+
writeString(data, offset, 'fmt ');
|
|
901
|
+
offset += 4;
|
|
902
|
+
// 过滤字节,一般为 0x10 = 16
|
|
903
|
+
data.setUint32(offset, 16, littleEdian);
|
|
904
|
+
offset += 4;
|
|
905
|
+
// 格式类别 (PCM形式采样数据)
|
|
906
|
+
data.setUint16(offset, 1, littleEdian);
|
|
907
|
+
offset += 2;
|
|
908
|
+
// 声道数
|
|
909
|
+
data.setUint16(offset, channelCount, littleEdian);
|
|
910
|
+
offset += 2;
|
|
911
|
+
// 采样率,每秒样本数,表示每个通道的播放速度
|
|
912
|
+
data.setUint32(offset, sampleRate, littleEdian);
|
|
913
|
+
offset += 4;
|
|
914
|
+
// 波形数据传输率 (每秒平均字节数) 声道数 × 采样频率 × 采样位数 / 8
|
|
915
|
+
data.setUint32(offset, channelCount * sampleRate * (sampleBits / 8), littleEdian);
|
|
916
|
+
offset += 4;
|
|
917
|
+
// 快数据调整数 采样一次占用字节数 声道数 × 采样位数 / 8
|
|
918
|
+
data.setUint16(offset, channelCount * (sampleBits / 8), littleEdian);
|
|
919
|
+
offset += 2;
|
|
920
|
+
// 采样位数
|
|
921
|
+
data.setUint16(offset, sampleBits, littleEdian);
|
|
922
|
+
offset += 2;
|
|
923
|
+
// 数据标识符
|
|
924
|
+
writeString(data, offset, 'data');
|
|
925
|
+
offset += 4;
|
|
926
|
+
// 采样数据总数,即数据总大小-44
|
|
927
|
+
data.setUint32(offset, bytes.byteLength, littleEdian);
|
|
928
|
+
offset += 4;
|
|
929
|
+
|
|
930
|
+
// 给wav头增加pcm体
|
|
931
|
+
for (var i = 0; i < bytes.byteLength;) {
|
|
932
|
+
data.setUint8(offset, bytes.getUint8(i));
|
|
933
|
+
offset++;
|
|
934
|
+
i++;
|
|
935
|
+
}
|
|
936
|
+
return data;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* 异常处理
|
|
941
|
+
* @static
|
|
942
|
+
* @param {*} message 错误消息
|
|
943
|
+
* @memberof Recorder
|
|
944
|
+
*/
|
|
945
|
+
}, {
|
|
946
|
+
key: "throwError",
|
|
947
|
+
value: function throwError(message) {
|
|
948
|
+
throw new Error(message);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* 在没有权限的时候,让弹出获取麦克风弹窗
|
|
953
|
+
*
|
|
954
|
+
*/
|
|
955
|
+
}, {
|
|
956
|
+
key: "getPermission",
|
|
957
|
+
value: (function () {
|
|
958
|
+
var _getPermission = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
|
959
|
+
var stream;
|
|
960
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
961
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
962
|
+
case 0:
|
|
963
|
+
if (navigator.mediaDevices) {
|
|
964
|
+
_context2.next = 2;
|
|
965
|
+
break;
|
|
966
|
+
}
|
|
967
|
+
return _context2.abrupt("return", Promise.reject(new Error('浏览器不支持 navigator.mediaDevices !')));
|
|
968
|
+
case 2:
|
|
969
|
+
_context2.next = 4;
|
|
970
|
+
return navigator.mediaDevices.getUserMedia({
|
|
971
|
+
audio: true
|
|
972
|
+
});
|
|
973
|
+
case 4:
|
|
974
|
+
stream = _context2.sent;
|
|
975
|
+
stream.getTracks().forEach(function (track) {
|
|
976
|
+
return track.stop();
|
|
977
|
+
});
|
|
978
|
+
case 6:
|
|
979
|
+
case "end":
|
|
980
|
+
return _context2.stop();
|
|
981
|
+
}
|
|
982
|
+
}, _callee2);
|
|
983
|
+
}));
|
|
984
|
+
function getPermission() {
|
|
985
|
+
return _getPermission.apply(this, arguments);
|
|
986
|
+
}
|
|
987
|
+
return getPermission;
|
|
988
|
+
}())
|
|
989
|
+
}]);
|
|
990
|
+
return Recorder;
|
|
991
|
+
}();
|
|
992
|
+
export default Recorder;
|