@besovideo/webrtc-player 0.8.95 → 0.8.97

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/README.md CHANGED
@@ -62,7 +62,7 @@ const { instance } = PuPlayer({
62
62
  // (可选) 指定video如何适应容器 (fill: 填充容器 ; contain :保持视频比例适应容器)
63
63
  videoFit: "fill",
64
64
  // (可选) 指定请求url路径前缀 可使用protocol+host 如:http://192.168.88.11:9780
65
- // apiPrefix: "/test_api/prefix",
65
+ apiPrefix: "/test_api/prefix",
66
66
 
67
67
  // (可选) 用于测试播放视频 (存在时优先使用url播放,为浏览器直接播放)
68
68
  // testUrl: "https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4",
@@ -171,9 +171,49 @@ instance.playerStatus : {
171
171
  // 设置录像状态
172
172
  Set(status: {type: "recordStart" | "recordStop"}): void;
173
173
  // 添加事件监听, type == "recordStop" recordInfo 才有值
174
- addEventListener(handle: ((status: {type: "recordStart" | "recordStop", recordInfo?: { data: Blob, cancelAutoDownload: () => void} }) => void)):void;
174
+ addEventListener(handle: ((status: {
175
+ type: "recordStart" | "recordStop",
176
+ recordInfo?: {
177
+ data: Blob; // 数据
178
+ startTime: number; // 录像开始时间 utc ms
179
+ endTime: number; // 录像结束时间 utc ms
180
+ duration: number; // 录像时长 ms
181
+ fileName: string; // 文件名
182
+ puOptions: {
183
+ id: string; // 设备名称
184
+ index: number; // 通道ID
185
+ name?: string; //设备名称,用于内部UI显示
186
+ indexName?: string; //通道名称,用于内部UI显示
187
+ },
188
+ //调用将取消自动下载,返回下载函数
189
+ cancelAutoDownload: () => {
190
+ //调用该接口,浏览器下载文件, filename 不填为默认的文件名,否则为[filename].webm
191
+ download(filename?: string): void;
192
+ }
193
+ }
194
+ }) => void)):void;
175
195
  // 移除事件监听
176
- removeEventListener(handle: ((status: {type: "recordStart" | "recordStop", recordInfo?: {data: Blob, cancelAutoDownload: () => void} }) => void)):void;
196
+ removeEventListener(handle: ((status: {
197
+ type: "recordStart" | "recordStop",
198
+ recordInfo?: {
199
+ data: Blob; // 数据
200
+ startTime: number; // 录像开始时间 utc ms
201
+ endTime: number; // 录像结束时间 utc ms
202
+ duration: number; // 录像时长 ms
203
+ fileName: string; // 文件名
204
+ puOptions: {
205
+ id: string; // 设备名称
206
+ index: number; // 通道ID
207
+ name?: string; //设备名称,用于内部UI显示
208
+ indexName?: string; //通道名称,用于内部UI显示
209
+ },
210
+ //调用将取消自动下载,返回下载函数
211
+ cancelAutoDownload: () => {
212
+ //调用该接口,浏览器下载文件, filename 不填为默认的文件名,否则为[filename].webm
213
+ download(filename?: string): void;
214
+ }
215
+ }
216
+ }) => void)):void;
177
217
  },
178
218
  rotate: {
179
219
  // 获取旋转状态,顺时针方向
@@ -214,9 +254,23 @@ instance.playerStatus : {
214
254
  exec(): void;
215
255
  // 添加事件监听,获取截图结果,
216
256
  // cancelAutoDownload 函数,调用会取消掉下载图片
217
- addEventListener(handle: ((status: {img?: Blob, cancelAutoDownload?: ()=>void})) => void)):void;
257
+ addEventListener(handle: ((
258
+ status: {
259
+ img?: Blob,
260
+ fileName?: string,
261
+ cancelAutoDownload?: ()=>{
262
+ download(fileName?: string): void //下载图片
263
+ }
264
+ })) => void)):void;
218
265
  // 移除事件监听
219
- removeEventListener(handle: ((status: {img?: Blob, cancelAutoDownload?: ()=>void })) => void)):void;
266
+ removeEventListener(handle: ((
267
+ status: {
268
+ img?: Blob,
269
+ fileName?: string,
270
+ cancelAutoDownload?: ()=>{
271
+ download(fileName?: string): void //下载图片
272
+ }
273
+ })) => void)):void;
220
274
  },
221
275
  informationGet: () => Promise<{
222
276
  //音频统计信息
@@ -321,7 +375,7 @@ const { instance } = Intercom({
321
375
  //(可选) 无法获取用户麦克风时
322
376
  onGetUserMediaFailed: () => {},
323
377
  // (可选) 指定请求url的前缀 方便代理请求
324
- // apiPrefix: "/test_api/prefix",
378
+ apiPrefix: "/test_api/prefix",
325
379
  });
326
380
 
327
381
  // open 异步 先关闭再开始建立连接 (可选参数: protocol = type 选择协议(type = "auto" | "webrtc" | "ws-bvrtc") 不填默认为auto)
@@ -1,3 +1,5 @@
1
+ @charset "UTF-8";
2
+
1
3
  /* sass-plugin-1:G:\develop\bvweb-player\node_modules\.pnpm\tippy.js@6.3.7\node_modules\tippy.js\dist\tippy.css */
2
4
  .tippy-box[data-animation=fade][data-state=hidden] {
3
5
  opacity: 0;
@@ -455,6 +457,20 @@
455
457
  width: 100px;
456
458
  border-radius: 5px;
457
459
  }
460
+ .bvplayer-recordState .blinking-element {
461
+ animation: blink 2s infinite;
462
+ }
463
+ @keyframes blink {
464
+ 0% {
465
+ opacity: 1;
466
+ }
467
+ 50% {
468
+ opacity: 0.1;
469
+ }
470
+ 100% {
471
+ opacity: 1;
472
+ }
473
+ }
458
474
  .bvplayer-video {
459
475
  display: block;
460
476
  box-sizing: border-box;
@@ -117,7 +117,7 @@ var bvPlayerCore = (() => {
117
117
  var define_processenv_default;
118
118
  var init_define_processenv = __esm({
119
119
  "<define:processenv>"() {
120
- define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.8.95", PROJECT_NAMESPACE: "bvplayer" };
120
+ define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.8.97", PROJECT_NAMESPACE: "bvplayer" };
121
121
  }
122
122
  });
123
123
 
@@ -7125,6 +7125,7 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
7125
7125
  description: audioCodecPrivate
7126
7126
  }
7127
7127
  } : void 0;
7128
+ let maxTimestamp = -1;
7128
7129
  handleEle((timestamp, data, bVideo, bKeyFrame) => {
7129
7130
  if (bVideo) {
7130
7131
  muxer.addVideoChunkRaw(data, bKeyFrame ? "key" : "delta", timestamp);
@@ -7133,9 +7134,15 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
7133
7134
  muxer.addAudioChunkRaw(data, "key", timestamp, config);
7134
7135
  }
7135
7136
  }
7137
+ if (maxTimestamp < timestamp) {
7138
+ maxTimestamp = timestamp;
7139
+ }
7136
7140
  });
7137
7141
  muxer.finalize();
7138
- return new Blob([muxer.target.buffer]);
7142
+ return {
7143
+ blob: new Blob([muxer.target.buffer]),
7144
+ maxTimestamp
7145
+ };
7139
7146
  });
7140
7147
  }
7141
7148
  var createMediaRecorder = (mediaStream, done, mediaRecorderPartner) => {
@@ -7173,6 +7180,7 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
7173
7180
  return mediaRecorder;
7174
7181
  };
7175
7182
  var createRecord = (_mediaStream, fileName, isDownload) => {
7183
+ const startTime = Date.now();
7176
7184
  const tempMediaStreams = _mediaStream.getTracks().map((item) => {
7177
7185
  const mediaStream2 = new MediaStream([item]);
7178
7186
  item.addEventListener("ended", () => {
@@ -7189,14 +7197,30 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
7189
7197
  const szWebM = [];
7190
7198
  function done(e) {
7191
7199
  return __async(this, null, function* () {
7200
+ let maxTimestamp = -1;
7192
7201
  szWebM.push(e.data);
7193
7202
  if (szWebM.length == mediaStreams.length) {
7194
- recordedChunks.push(yield combinaWebM(...szWebM));
7203
+ const { blob: blobWebM, maxTimestamp: _maxTimestamp } = yield combinaWebM(
7204
+ ...szWebM
7205
+ );
7206
+ recordedChunks.push(blobWebM);
7207
+ if (_maxTimestamp > maxTimestamp) {
7208
+ maxTimestamp = _maxTimestamp;
7209
+ }
7195
7210
  const blob = new Blob(recordedChunks, {
7196
7211
  type: "video/webm"
7197
7212
  });
7198
- if (yield isDownload(blob)) {
7199
- file_default.downLoadBlob(blob, fileName, "webm");
7213
+ const downloadFile = (inFileName) => {
7214
+ file_default.downLoadBlob(blob, inFileName ? inFileName : fileName, "webm");
7215
+ };
7216
+ if (isDownload(blob, { duration: maxTimestamp / 1e3, startTime, endTime: startTime + maxTimestamp / 1e3, fileName }, () => {
7217
+ return {
7218
+ download(file2) {
7219
+ downloadFile(file2);
7220
+ }
7221
+ };
7222
+ })) {
7223
+ downloadFile(fileName);
7200
7224
  }
7201
7225
  recordedChunks = [];
7202
7226
  }
@@ -7228,8 +7252,13 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
7228
7252
  const blob = yield canvasToBlob(canvas);
7229
7253
  return {
7230
7254
  blob,
7231
- download() {
7232
- file_default.downLoadBlob(blob, fileName, "png");
7255
+ fileName,
7256
+ download(fileNameCaller) {
7257
+ file_default.downLoadBlob(
7258
+ blob,
7259
+ fileNameCaller ? fileNameCaller : fileName,
7260
+ "png"
7261
+ );
7233
7262
  }
7234
7263
  };
7235
7264
  } catch (e) {
@@ -7250,19 +7279,24 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
7250
7279
  try {
7251
7280
  const mediaStream = stream || element.captureStream(25);
7252
7281
  let gOnMediaHolder = void 0;
7253
- const mediaRecorder = createRecord(mediaStream, fileName, (blob) => __async(void 0, null, function* () {
7254
- if (gOnMediaHolder) {
7255
- const holder = gOnMediaHolder;
7256
- gOnMediaHolder = void 0;
7257
- let bDownload = true;
7258
- const cancelAutoDownload = () => {
7259
- bDownload = false;
7260
- };
7261
- yield holder(blob, cancelAutoDownload);
7262
- return bDownload;
7282
+ const mediaRecorder = createRecord(
7283
+ mediaStream,
7284
+ fileName,
7285
+ (blob, metaInfo, downloadRecordGetter) => {
7286
+ if (gOnMediaHolder) {
7287
+ const holder = gOnMediaHolder;
7288
+ gOnMediaHolder = void 0;
7289
+ let bDownload = true;
7290
+ const cancelAutoDownload = () => {
7291
+ bDownload = false;
7292
+ return downloadRecordGetter();
7293
+ };
7294
+ holder(blob, metaInfo, cancelAutoDownload);
7295
+ return bDownload;
7296
+ }
7297
+ return true;
7263
7298
  }
7264
- return true;
7265
- }));
7299
+ );
7266
7300
  logger_default.info("\u5F55\u5236\u5B9E\u4F8B", mediaRecorder);
7267
7301
  return [
7268
7302
  mediaRecorder,
@@ -12831,10 +12865,20 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
12831
12865
  }
12832
12866
  init(_container) {
12833
12867
  const el = this.el;
12834
- const svgRecord = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 256 256" style="vertical-align: sub;" ><rect width="256" height="256" fill="none"/><circle cx="127" cy="129" r="81" fill="#dd2c2c" fill-rule="evenodd"/></svg>`;
12868
+ const svgRecord = `<svg class='blinking-element' xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 256 256" style="vertical-align: sub;" ><rect width="256" height="256" fill="none"/><circle cx="127" cy="129" r="81" fill="#dd2c2c" fill-rule="evenodd"/></svg>`;
12835
12869
  el.style.display = "none";
12836
- const spinEl = core_default.dom.create("span");
12837
- spinEl.innerHTML = `${svgRecord} 00:00:00`;
12870
+ const spinEl = core_default.dom.create("div");
12871
+ spinEl.innerHTML = `${svgRecord}`;
12872
+ spinEl.style.color = "black";
12873
+ spinEl.style.backgroundColor = "white";
12874
+ spinEl.style.margin = "5px 5px";
12875
+ spinEl.style.padding = "2px 5px 2px 1px";
12876
+ spinEl.style.top = "5px";
12877
+ spinEl.style.left = "5px";
12878
+ spinEl.style.borderRadius = "4px";
12879
+ const sliceSpan = document.createElement("span");
12880
+ spinEl.appendChild(sliceSpan);
12881
+ sliceSpan.innerHTML = "00:00:00";
12838
12882
  core_default.dom.append(el, spinEl);
12839
12883
  this.spanEle = spinEl;
12840
12884
  let recordStart = 0;
@@ -12849,7 +12893,7 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
12849
12893
  const mins = formatTime(lastTime, 60);
12850
12894
  const seconds = Math.floor(lastTime % 60);
12851
12895
  const fomatSeconds = seconds > 9 ? seconds : "0" + seconds;
12852
- spinEl.innerHTML = `${svgRecord} <span>${hour + mins + fomatSeconds}</span>`;
12896
+ sliceSpan.innerHTML = `${hour + mins + fomatSeconds}`;
12853
12897
  }
12854
12898
  this.addEventListener("RecordStart", () => {
12855
12899
  if (this.el) {
@@ -12864,7 +12908,7 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
12864
12908
  });
12865
12909
  this.addEventListener("RecordEnd", () => {
12866
12910
  if (this.el) {
12867
- spinEl.innerHTML = `${svgRecord} <span>00:00:00</span>`;
12911
+ sliceSpan.innerHTML = "00:00:00";
12868
12912
  this.el.style.display = "none";
12869
12913
  }
12870
12914
  if (this.intervalToken) {
@@ -12914,6 +12958,7 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
12914
12958
  this._video = new video_default({
12915
12959
  puOptions: options == null ? void 0 : options.puOptions
12916
12960
  });
12961
+ this._puOptions = options == null ? void 0 : options.puOptions;
12917
12962
  this._spinner = new spinner_default({ spin: false });
12918
12963
  this._toast = new toast_default();
12919
12964
  this._mask = new mask_default({ visible: false });
@@ -13128,8 +13173,14 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
13128
13173
  let bDownload = true;
13129
13174
  this.dispatch("screenshot", screenshotResult && screenshotResult.blob ? {
13130
13175
  img: screenshotResult.blob,
13176
+ fileName: screenshotResult.fileName,
13131
13177
  cancelAutoDownload() {
13132
13178
  bDownload = false;
13179
+ return {
13180
+ download(fileName) {
13181
+ screenshotResult == null ? void 0 : screenshotResult.download(fileName);
13182
+ }
13183
+ };
13133
13184
  }
13134
13185
  } : void 0);
13135
13186
  if (bDownload && (screenshotResult == null ? void 0 : screenshotResult.download)) {
@@ -13189,12 +13240,15 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
13189
13240
  if ((_a = this._panel) == null ? void 0 : _a.controller.RecordButton) {
13190
13241
  (_b = this._panel) == null ? void 0 : _b.controller.RecordButton.dispatch("click");
13191
13242
  } else {
13192
- this._video.recordStop((blob, cancelAutoDownload) => {
13193
- this.dispatch("recordStop", {
13243
+ this._video.recordStop((blob, mataInfo, cancelAutoDownload) => {
13244
+ this.dispatch("recordStop", __spreadProps(__spreadValues({
13245
+ puOptions: this._puOptions
13246
+ }, mataInfo), {
13194
13247
  data: blob,
13195
13248
  cancelAutoDownload
13196
- });
13249
+ }));
13197
13250
  this._recordState.dispatch("RecordEnd");
13251
+ return false;
13198
13252
  });
13199
13253
  }
13200
13254
  }
@@ -13260,12 +13314,15 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
13260
13314
  this._recordState.dispatch("RecordStart");
13261
13315
  });
13262
13316
  panel.controller.addEventListener("recordStop", () => {
13263
- this._video.recordStop((blob, cancelAutoDownload) => {
13264
- this.dispatch("recordStop", {
13317
+ this._video.recordStop((blob, metaInfo, cancelAutoDownload) => {
13318
+ this.dispatch("recordStop", __spreadProps(__spreadValues({
13319
+ puOptions: this._puOptions
13320
+ }, metaInfo), {
13265
13321
  data: blob,
13266
13322
  cancelAutoDownload
13267
- });
13323
+ }));
13268
13324
  this._recordState.dispatch("RecordEnd");
13325
+ return false;
13269
13326
  });
13270
13327
  });
13271
13328
  panel.controller.addEventListener("rotate", () => {
@@ -13573,6 +13630,7 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
13573
13630
  // smooth: 播放平滑度。[1,7],值越小越实时。
13574
13631
  // algokey: 加解密算法:密钥。格式:算法:base64(密钥)。例如: SM4:MTIzNDU2Nzg=
13575
13632
  constructor() {
13633
+ console.log("================== bvrtc version: 1.0.1 20241028 ==================");
13576
13634
  this.hplayer = 0;
13577
13635
  this.canvas = null;
13578
13636
  this.dialogid = "";
@@ -14501,6 +14559,20 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
14501
14559
  this.audioCtx.close();
14502
14560
  this.audioCtx = null;
14503
14561
  };
14562
+ var woker_str = `
14563
+ class BVAudioProcessor extends AudioWorkletProcessor {
14564
+ process(inputs, outputs, parameters) {
14565
+ const inputdata = inputs[0][0];
14566
+ this.port.postMessage(inputdata);
14567
+ return true;
14568
+ }
14569
+ }
14570
+ registerProcessor('bv-audio-processor', BVAudioProcessor);
14571
+ `;
14572
+ var audioProcessorBolb = new Blob([woker_str], {
14573
+ type: "application/javascript"
14574
+ });
14575
+ var audioProcessorUrl = URL.createObjectURL(audioProcessorBolb);
14504
14576
  function BVPcmRecorder(config, cb) {
14505
14577
  if (!config) {
14506
14578
  config = {
@@ -14512,7 +14584,7 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
14512
14584
  };
14513
14585
  }
14514
14586
  this.config = config;
14515
- this.sampleRate = new (window.AudioContext || window.webkitAudioContext)().sampleRate;
14587
+ this.sampleRate = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: this.config.sampleRate }).sampleRate;
14516
14588
  this.fftSize = 512;
14517
14589
  this.analyser = null;
14518
14590
  this.audioInput = null;
@@ -14522,20 +14594,23 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
14522
14594
  this.audioData = null;
14523
14595
  this.audioSize = 0;
14524
14596
  this.cb = cb;
14525
- this.init();
14526
14597
  console.log("sampleRate " + this.sampleRate);
14527
14598
  }
14528
14599
  BVPcmRecorder.prototype.start = function() {
14529
- navigator.mediaDevices.getUserMedia({
14530
- audio: true
14531
- }).then((stream) => {
14532
- this.audioInput = this.context.createMediaStreamSource(stream);
14533
- }, (error2) => {
14534
- console.error(error2);
14535
- }).then(() => {
14536
- this.audioInput.connect(this.analyser);
14537
- this.analyser.connect(this.recorder);
14538
- this.recorder.connect(this.context.destination);
14600
+ return __async(this, null, function* () {
14601
+ yield this.init();
14602
+ navigator.mediaDevices.getUserMedia({
14603
+ audio: true,
14604
+ sampleRate: this.config.sampleRate
14605
+ }).then((stream) => {
14606
+ this.audioInput = this.context.createMediaStreamSource(stream);
14607
+ }, (error2) => {
14608
+ console.error(error2);
14609
+ }).then(() => {
14610
+ this.audioInput.connect(this.analyser);
14611
+ this.analyser.connect(this.recorder);
14612
+ this.recorder.connect(this.context.destination);
14613
+ });
14539
14614
  });
14540
14615
  };
14541
14616
  BVPcmRecorder.prototype.stop = function() {
@@ -14543,23 +14618,21 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
14543
14618
  this.audioInput.disconnect();
14544
14619
  if (this.recorder)
14545
14620
  this.recorder.disconnect();
14621
+ if (this.context)
14622
+ this.context.close();
14546
14623
  };
14547
14624
  BVPcmRecorder.prototype.init = function() {
14548
- this.context = new (window.AudioContext || window.webkitAudioContext)();
14549
- this.analyser = this.context.createAnalyser();
14550
- this.analyser.fftSize = this.fftSize;
14551
- const createScript = this.context.createScriptProcessor || this.context.createJavaScriptNode;
14552
- this.recorder = createScript.apply(
14553
- this.context,
14554
- [this.fftSize, this.config.numberChannels, this.config.numberChannels]
14555
- );
14556
- this.recorder.onaudioprocess = this.onaudioprocess.bind(this);
14557
- };
14558
- BVPcmRecorder.prototype.onaudioprocess = function(e) {
14559
- if (this.config.numberChannels === 1) {
14560
- const data = e.inputBuffer.getChannelData(0);
14561
- this.handlePcm(new Float32Array(data));
14562
- }
14625
+ return __async(this, null, function* () {
14626
+ this.context = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: this.config.sampleRate });
14627
+ this.analyser = this.context.createAnalyser();
14628
+ this.analyser.fftSize = this.fftSize;
14629
+ yield this.context.audioWorklet.addModule(audioProcessorUrl);
14630
+ this.recorder = new AudioWorkletNode(this.context, "bv-audio-processor");
14631
+ this.recorder.port.onmessage = (e) => {
14632
+ if (e.data)
14633
+ this.handlePcm(e.data);
14634
+ };
14635
+ });
14563
14636
  };
14564
14637
  BVPcmRecorder.prototype.handlePcm = function(bytes) {
14565
14638
  if (bytes[0] === 0 && bytes[1] === 0)
@@ -16336,6 +16409,7 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
16336
16409
  return player.addEventListener("screenshot", (data) => {
16337
16410
  handleUtils.dispatch({
16338
16411
  img: data == null ? void 0 : data.img,
16412
+ fileName: data == null ? void 0 : data.fileName,
16339
16413
  cancelAutoDownload: data == null ? void 0 : data.cancelAutoDownload
16340
16414
  });
16341
16415
  });
package/dist/main.es.css CHANGED
@@ -1,3 +1,5 @@
1
+ @charset "UTF-8";
2
+
1
3
  /* sass-plugin-0:G:\develop\bvweb-player\node_modules\.pnpm\tippy.js@6.3.7\node_modules\tippy.js\dist\tippy.css */
2
4
  .tippy-box[data-animation=fade][data-state=hidden] {
3
5
  opacity: 0;
@@ -455,6 +457,20 @@
455
457
  width: 100px;
456
458
  border-radius: 5px;
457
459
  }
460
+ .bvplayer-recordState .blinking-element {
461
+ animation: blink 2s infinite;
462
+ }
463
+ @keyframes blink {
464
+ 0% {
465
+ opacity: 1;
466
+ }
467
+ 50% {
468
+ opacity: 0.1;
469
+ }
470
+ 100% {
471
+ opacity: 1;
472
+ }
473
+ }
458
474
  .bvplayer-video {
459
475
  display: block;
460
476
  box-sizing: border-box;
package/dist/main.es.js CHANGED
@@ -111,7 +111,7 @@ var __async = (__this, __arguments, generator) => {
111
111
  var define_processenv_default;
112
112
  var init_define_processenv = __esm({
113
113
  "<define:processenv>"() {
114
- define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.8.95", PROJECT_NAMESPACE: "bvplayer" };
114
+ define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.8.97", PROJECT_NAMESPACE: "bvplayer" };
115
115
  }
116
116
  });
117
117
 
@@ -7109,6 +7109,7 @@ function combinaWebM(webM1, webM2) {
7109
7109
  description: audioCodecPrivate
7110
7110
  }
7111
7111
  } : void 0;
7112
+ let maxTimestamp = -1;
7112
7113
  handleEle((timestamp, data, bVideo, bKeyFrame) => {
7113
7114
  if (bVideo) {
7114
7115
  muxer.addVideoChunkRaw(data, bKeyFrame ? "key" : "delta", timestamp);
@@ -7117,9 +7118,15 @@ function combinaWebM(webM1, webM2) {
7117
7118
  muxer.addAudioChunkRaw(data, "key", timestamp, config);
7118
7119
  }
7119
7120
  }
7121
+ if (maxTimestamp < timestamp) {
7122
+ maxTimestamp = timestamp;
7123
+ }
7120
7124
  });
7121
7125
  muxer.finalize();
7122
- return new Blob([muxer.target.buffer]);
7126
+ return {
7127
+ blob: new Blob([muxer.target.buffer]),
7128
+ maxTimestamp
7129
+ };
7123
7130
  });
7124
7131
  }
7125
7132
  var createMediaRecorder = (mediaStream, done, mediaRecorderPartner) => {
@@ -7157,6 +7164,7 @@ var createMediaRecorder = (mediaStream, done, mediaRecorderPartner) => {
7157
7164
  return mediaRecorder;
7158
7165
  };
7159
7166
  var createRecord = (_mediaStream, fileName, isDownload) => {
7167
+ const startTime = Date.now();
7160
7168
  const tempMediaStreams = _mediaStream.getTracks().map((item) => {
7161
7169
  const mediaStream2 = new MediaStream([item]);
7162
7170
  item.addEventListener("ended", () => {
@@ -7173,14 +7181,30 @@ var createRecord = (_mediaStream, fileName, isDownload) => {
7173
7181
  const szWebM = [];
7174
7182
  function done(e) {
7175
7183
  return __async(this, null, function* () {
7184
+ let maxTimestamp = -1;
7176
7185
  szWebM.push(e.data);
7177
7186
  if (szWebM.length == mediaStreams.length) {
7178
- recordedChunks.push(yield combinaWebM(...szWebM));
7187
+ const { blob: blobWebM, maxTimestamp: _maxTimestamp } = yield combinaWebM(
7188
+ ...szWebM
7189
+ );
7190
+ recordedChunks.push(blobWebM);
7191
+ if (_maxTimestamp > maxTimestamp) {
7192
+ maxTimestamp = _maxTimestamp;
7193
+ }
7179
7194
  const blob = new Blob(recordedChunks, {
7180
7195
  type: "video/webm"
7181
7196
  });
7182
- if (yield isDownload(blob)) {
7183
- file_default.downLoadBlob(blob, fileName, "webm");
7197
+ const downloadFile = (inFileName) => {
7198
+ file_default.downLoadBlob(blob, inFileName ? inFileName : fileName, "webm");
7199
+ };
7200
+ if (isDownload(blob, { duration: maxTimestamp / 1e3, startTime, endTime: startTime + maxTimestamp / 1e3, fileName }, () => {
7201
+ return {
7202
+ download(file2) {
7203
+ downloadFile(file2);
7204
+ }
7205
+ };
7206
+ })) {
7207
+ downloadFile(fileName);
7184
7208
  }
7185
7209
  recordedChunks = [];
7186
7210
  }
@@ -7212,8 +7236,13 @@ var screenshotByCanvas = (_0, ..._1) => __async(void 0, [_0, ..._1], function* (
7212
7236
  const blob = yield canvasToBlob(canvas);
7213
7237
  return {
7214
7238
  blob,
7215
- download() {
7216
- file_default.downLoadBlob(blob, fileName, "png");
7239
+ fileName,
7240
+ download(fileNameCaller) {
7241
+ file_default.downLoadBlob(
7242
+ blob,
7243
+ fileNameCaller ? fileNameCaller : fileName,
7244
+ "png"
7245
+ );
7217
7246
  }
7218
7247
  };
7219
7248
  } catch (e) {
@@ -7234,19 +7263,24 @@ var record = (element, stream, fileName = `record_${Date.now()}`) => {
7234
7263
  try {
7235
7264
  const mediaStream = stream || element.captureStream(25);
7236
7265
  let gOnMediaHolder = void 0;
7237
- const mediaRecorder = createRecord(mediaStream, fileName, (blob) => __async(void 0, null, function* () {
7238
- if (gOnMediaHolder) {
7239
- const holder = gOnMediaHolder;
7240
- gOnMediaHolder = void 0;
7241
- let bDownload = true;
7242
- const cancelAutoDownload = () => {
7243
- bDownload = false;
7244
- };
7245
- yield holder(blob, cancelAutoDownload);
7246
- return bDownload;
7266
+ const mediaRecorder = createRecord(
7267
+ mediaStream,
7268
+ fileName,
7269
+ (blob, metaInfo, downloadRecordGetter) => {
7270
+ if (gOnMediaHolder) {
7271
+ const holder = gOnMediaHolder;
7272
+ gOnMediaHolder = void 0;
7273
+ let bDownload = true;
7274
+ const cancelAutoDownload = () => {
7275
+ bDownload = false;
7276
+ return downloadRecordGetter();
7277
+ };
7278
+ holder(blob, metaInfo, cancelAutoDownload);
7279
+ return bDownload;
7280
+ }
7281
+ return true;
7247
7282
  }
7248
- return true;
7249
- }));
7283
+ );
7250
7284
  logger_default.info("\u5F55\u5236\u5B9E\u4F8B", mediaRecorder);
7251
7285
  return [
7252
7286
  mediaRecorder,
@@ -12815,10 +12849,20 @@ var RecordStatePlugin = class extends Plugin {
12815
12849
  }
12816
12850
  init(_container) {
12817
12851
  const el = this.el;
12818
- const svgRecord = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 256 256" style="vertical-align: sub;" ><rect width="256" height="256" fill="none"/><circle cx="127" cy="129" r="81" fill="#dd2c2c" fill-rule="evenodd"/></svg>`;
12852
+ const svgRecord = `<svg class='blinking-element' xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 256 256" style="vertical-align: sub;" ><rect width="256" height="256" fill="none"/><circle cx="127" cy="129" r="81" fill="#dd2c2c" fill-rule="evenodd"/></svg>`;
12819
12853
  el.style.display = "none";
12820
- const spinEl = core_default.dom.create("span");
12821
- spinEl.innerHTML = `${svgRecord} 00:00:00`;
12854
+ const spinEl = core_default.dom.create("div");
12855
+ spinEl.innerHTML = `${svgRecord}`;
12856
+ spinEl.style.color = "black";
12857
+ spinEl.style.backgroundColor = "white";
12858
+ spinEl.style.margin = "5px 5px";
12859
+ spinEl.style.padding = "2px 5px 2px 1px";
12860
+ spinEl.style.top = "5px";
12861
+ spinEl.style.left = "5px";
12862
+ spinEl.style.borderRadius = "4px";
12863
+ const sliceSpan = document.createElement("span");
12864
+ spinEl.appendChild(sliceSpan);
12865
+ sliceSpan.innerHTML = "00:00:00";
12822
12866
  core_default.dom.append(el, spinEl);
12823
12867
  this.spanEle = spinEl;
12824
12868
  let recordStart = 0;
@@ -12833,7 +12877,7 @@ var RecordStatePlugin = class extends Plugin {
12833
12877
  const mins = formatTime(lastTime, 60);
12834
12878
  const seconds = Math.floor(lastTime % 60);
12835
12879
  const fomatSeconds = seconds > 9 ? seconds : "0" + seconds;
12836
- spinEl.innerHTML = `${svgRecord} <span>${hour + mins + fomatSeconds}</span>`;
12880
+ sliceSpan.innerHTML = `${hour + mins + fomatSeconds}`;
12837
12881
  }
12838
12882
  this.addEventListener("RecordStart", () => {
12839
12883
  if (this.el) {
@@ -12848,7 +12892,7 @@ var RecordStatePlugin = class extends Plugin {
12848
12892
  });
12849
12893
  this.addEventListener("RecordEnd", () => {
12850
12894
  if (this.el) {
12851
- spinEl.innerHTML = `${svgRecord} <span>00:00:00</span>`;
12895
+ sliceSpan.innerHTML = "00:00:00";
12852
12896
  this.el.style.display = "none";
12853
12897
  }
12854
12898
  if (this.intervalToken) {
@@ -12898,6 +12942,7 @@ var PlayerPlugin = class extends Plugin {
12898
12942
  this._video = new video_default({
12899
12943
  puOptions: options == null ? void 0 : options.puOptions
12900
12944
  });
12945
+ this._puOptions = options == null ? void 0 : options.puOptions;
12901
12946
  this._spinner = new spinner_default({ spin: false });
12902
12947
  this._toast = new toast_default();
12903
12948
  this._mask = new mask_default({ visible: false });
@@ -13112,8 +13157,14 @@ var PlayerPlugin = class extends Plugin {
13112
13157
  let bDownload = true;
13113
13158
  this.dispatch("screenshot", screenshotResult && screenshotResult.blob ? {
13114
13159
  img: screenshotResult.blob,
13160
+ fileName: screenshotResult.fileName,
13115
13161
  cancelAutoDownload() {
13116
13162
  bDownload = false;
13163
+ return {
13164
+ download(fileName) {
13165
+ screenshotResult == null ? void 0 : screenshotResult.download(fileName);
13166
+ }
13167
+ };
13117
13168
  }
13118
13169
  } : void 0);
13119
13170
  if (bDownload && (screenshotResult == null ? void 0 : screenshotResult.download)) {
@@ -13173,12 +13224,15 @@ var PlayerPlugin = class extends Plugin {
13173
13224
  if ((_a = this._panel) == null ? void 0 : _a.controller.RecordButton) {
13174
13225
  (_b = this._panel) == null ? void 0 : _b.controller.RecordButton.dispatch("click");
13175
13226
  } else {
13176
- this._video.recordStop((blob, cancelAutoDownload) => {
13177
- this.dispatch("recordStop", {
13227
+ this._video.recordStop((blob, mataInfo, cancelAutoDownload) => {
13228
+ this.dispatch("recordStop", __spreadProps(__spreadValues({
13229
+ puOptions: this._puOptions
13230
+ }, mataInfo), {
13178
13231
  data: blob,
13179
13232
  cancelAutoDownload
13180
- });
13233
+ }));
13181
13234
  this._recordState.dispatch("RecordEnd");
13235
+ return false;
13182
13236
  });
13183
13237
  }
13184
13238
  }
@@ -13244,12 +13298,15 @@ var PlayerPlugin = class extends Plugin {
13244
13298
  this._recordState.dispatch("RecordStart");
13245
13299
  });
13246
13300
  panel.controller.addEventListener("recordStop", () => {
13247
- this._video.recordStop((blob, cancelAutoDownload) => {
13248
- this.dispatch("recordStop", {
13301
+ this._video.recordStop((blob, metaInfo, cancelAutoDownload) => {
13302
+ this.dispatch("recordStop", __spreadProps(__spreadValues({
13303
+ puOptions: this._puOptions
13304
+ }, metaInfo), {
13249
13305
  data: blob,
13250
13306
  cancelAutoDownload
13251
- });
13307
+ }));
13252
13308
  this._recordState.dispatch("RecordEnd");
13309
+ return false;
13253
13310
  });
13254
13311
  });
13255
13312
  panel.controller.addEventListener("rotate", () => {
@@ -13557,6 +13614,7 @@ var BVMedia = class {
13557
13614
  // smooth: 播放平滑度。[1,7],值越小越实时。
13558
13615
  // algokey: 加解密算法:密钥。格式:算法:base64(密钥)。例如: SM4:MTIzNDU2Nzg=
13559
13616
  constructor() {
13617
+ console.log("================== bvrtc version: 1.0.1 20241028 ==================");
13560
13618
  this.hplayer = 0;
13561
13619
  this.canvas = null;
13562
13620
  this.dialogid = "";
@@ -14485,6 +14543,20 @@ BVPCMPlayer.prototype.destroy = function() {
14485
14543
  this.audioCtx.close();
14486
14544
  this.audioCtx = null;
14487
14545
  };
14546
+ var woker_str = `
14547
+ class BVAudioProcessor extends AudioWorkletProcessor {
14548
+ process(inputs, outputs, parameters) {
14549
+ const inputdata = inputs[0][0];
14550
+ this.port.postMessage(inputdata);
14551
+ return true;
14552
+ }
14553
+ }
14554
+ registerProcessor('bv-audio-processor', BVAudioProcessor);
14555
+ `;
14556
+ var audioProcessorBolb = new Blob([woker_str], {
14557
+ type: "application/javascript"
14558
+ });
14559
+ var audioProcessorUrl = URL.createObjectURL(audioProcessorBolb);
14488
14560
  function BVPcmRecorder(config, cb) {
14489
14561
  if (!config) {
14490
14562
  config = {
@@ -14496,7 +14568,7 @@ function BVPcmRecorder(config, cb) {
14496
14568
  };
14497
14569
  }
14498
14570
  this.config = config;
14499
- this.sampleRate = new (window.AudioContext || window.webkitAudioContext)().sampleRate;
14571
+ this.sampleRate = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: this.config.sampleRate }).sampleRate;
14500
14572
  this.fftSize = 512;
14501
14573
  this.analyser = null;
14502
14574
  this.audioInput = null;
@@ -14506,20 +14578,23 @@ function BVPcmRecorder(config, cb) {
14506
14578
  this.audioData = null;
14507
14579
  this.audioSize = 0;
14508
14580
  this.cb = cb;
14509
- this.init();
14510
14581
  console.log("sampleRate " + this.sampleRate);
14511
14582
  }
14512
14583
  BVPcmRecorder.prototype.start = function() {
14513
- navigator.mediaDevices.getUserMedia({
14514
- audio: true
14515
- }).then((stream) => {
14516
- this.audioInput = this.context.createMediaStreamSource(stream);
14517
- }, (error2) => {
14518
- console.error(error2);
14519
- }).then(() => {
14520
- this.audioInput.connect(this.analyser);
14521
- this.analyser.connect(this.recorder);
14522
- this.recorder.connect(this.context.destination);
14584
+ return __async(this, null, function* () {
14585
+ yield this.init();
14586
+ navigator.mediaDevices.getUserMedia({
14587
+ audio: true,
14588
+ sampleRate: this.config.sampleRate
14589
+ }).then((stream) => {
14590
+ this.audioInput = this.context.createMediaStreamSource(stream);
14591
+ }, (error2) => {
14592
+ console.error(error2);
14593
+ }).then(() => {
14594
+ this.audioInput.connect(this.analyser);
14595
+ this.analyser.connect(this.recorder);
14596
+ this.recorder.connect(this.context.destination);
14597
+ });
14523
14598
  });
14524
14599
  };
14525
14600
  BVPcmRecorder.prototype.stop = function() {
@@ -14527,23 +14602,21 @@ BVPcmRecorder.prototype.stop = function() {
14527
14602
  this.audioInput.disconnect();
14528
14603
  if (this.recorder)
14529
14604
  this.recorder.disconnect();
14605
+ if (this.context)
14606
+ this.context.close();
14530
14607
  };
14531
14608
  BVPcmRecorder.prototype.init = function() {
14532
- this.context = new (window.AudioContext || window.webkitAudioContext)();
14533
- this.analyser = this.context.createAnalyser();
14534
- this.analyser.fftSize = this.fftSize;
14535
- const createScript = this.context.createScriptProcessor || this.context.createJavaScriptNode;
14536
- this.recorder = createScript.apply(
14537
- this.context,
14538
- [this.fftSize, this.config.numberChannels, this.config.numberChannels]
14539
- );
14540
- this.recorder.onaudioprocess = this.onaudioprocess.bind(this);
14541
- };
14542
- BVPcmRecorder.prototype.onaudioprocess = function(e) {
14543
- if (this.config.numberChannels === 1) {
14544
- const data = e.inputBuffer.getChannelData(0);
14545
- this.handlePcm(new Float32Array(data));
14546
- }
14609
+ return __async(this, null, function* () {
14610
+ this.context = new (window.AudioContext || window.webkitAudioContext)({ sampleRate: this.config.sampleRate });
14611
+ this.analyser = this.context.createAnalyser();
14612
+ this.analyser.fftSize = this.fftSize;
14613
+ yield this.context.audioWorklet.addModule(audioProcessorUrl);
14614
+ this.recorder = new AudioWorkletNode(this.context, "bv-audio-processor");
14615
+ this.recorder.port.onmessage = (e) => {
14616
+ if (e.data)
14617
+ this.handlePcm(e.data);
14618
+ };
14619
+ });
14547
14620
  };
14548
14621
  BVPcmRecorder.prototype.handlePcm = function(bytes) {
14549
14622
  if (bytes[0] === 0 && bytes[1] === 0)
@@ -16320,6 +16393,7 @@ function CreatePlayerState(player) {
16320
16393
  return player.addEventListener("screenshot", (data) => {
16321
16394
  handleUtils.dispatch({
16322
16395
  img: data == null ? void 0 : data.img,
16396
+ fileName: data == null ? void 0 : data.fileName,
16323
16397
  cancelAutoDownload: data == null ? void 0 : data.cancelAutoDownload
16324
16398
  });
16325
16399
  });
@@ -1,5 +1,6 @@
1
1
  import PlayerPlugin from "../../plugins/player";
2
2
  import { IDataHandle } from "src/core/events";
3
+ import { IRecordStopInfo } from "src/plugins/player/event";
3
4
  type EnumRotate = "Rotate0" | "Rotate90" | "Rotate180" | "Rotate270";
4
5
  export type IPlayerState = ReturnType<typeof CreatePlayerState>;
5
6
  export declare function CreatePlayerState(player: PlayerPlugin): {
@@ -8,10 +9,7 @@ export declare function CreatePlayerState(player: PlayerPlugin): {
8
9
  information: IDataHandle<boolean>;
9
10
  record: IDataHandle<{
10
11
  type: "recordStart" | "recordStop";
11
- recordInfo?: {
12
- data: Blob;
13
- cancelAutoDownload: () => void;
14
- } | undefined;
12
+ recordInfo?: IRecordStopInfo | undefined;
15
13
  }>;
16
14
  rotate: IDataHandle<{
17
15
  type: EnumRotate;
@@ -24,15 +22,18 @@ export declare function CreatePlayerState(player: PlayerPlugin): {
24
22
  }>;
25
23
  screenshot: IDataHandle<{
26
24
  img?: Blob | undefined;
25
+ fileName?: string | undefined;
27
26
  cancelAutoDownload?: (() => void) | undefined;
28
27
  }> | {
29
28
  exec(): void;
30
29
  addEventListener: (handle: (data: {
31
30
  img?: Blob | undefined;
31
+ fileName?: string | undefined;
32
32
  cancelAutoDownload?: (() => void) | undefined;
33
33
  }) => void) => () => void;
34
34
  removeEventListener: (handle: (data: {
35
35
  img?: Blob | undefined;
36
+ fileName?: string | undefined;
36
37
  cancelAutoDownload?: (() => void) | undefined;
37
38
  }) => void) => void;
38
39
  };
@@ -1,3 +1,4 @@
1
+ import { IPuOption } from "src/main";
1
2
  import { IPluginEvent, IPluginEventMap } from "../../plugins/types";
2
3
  import PlayerPlugin, { PLAYER_MODES } from "./index";
3
4
  interface IPlayerEvent extends IPluginEvent {
@@ -15,6 +16,17 @@ interface IRotateEvent extends IPlayerEvent {
15
16
  name: "rotateEvent";
16
17
  rotateDeg: number;
17
18
  }
19
+ export interface IRecordStopInfo {
20
+ data: Blob;
21
+ startTime: number;
22
+ endTime: number;
23
+ duration: number;
24
+ puOptions: IPuOption;
25
+ fileName: string;
26
+ cancelAutoDownload: () => {
27
+ download(filename?: string): void;
28
+ };
29
+ }
18
30
  export interface IPlayerPluginEventMap extends IPluginEventMap {
19
31
  init: IInitEvent;
20
32
  closeWebrtc: ICloseWebrtcEvent;
@@ -22,13 +34,13 @@ export interface IPlayerPluginEventMap extends IPluginEventMap {
22
34
  close: IPlayerEvent;
23
35
  contextmenu: Event;
24
36
  recordStart: undefined;
25
- recordStop: {
26
- data: Blob;
27
- cancelAutoDownload: () => void;
28
- };
37
+ recordStop: IRecordStopInfo;
29
38
  screenshot: undefined | {
30
39
  img: Blob;
31
- cancelAutoDownload: () => void;
40
+ fileName: string;
41
+ cancelAutoDownload: () => {
42
+ download(fileName?: string): void;
43
+ };
32
44
  };
33
45
  fullscreen: boolean;
34
46
  rotate: IRotateEvent;
@@ -56,6 +56,7 @@ declare class PlayerPlugin extends Plugin<HTMLDivElement, IPlayerPluginEventMap>
56
56
  private _videoOption?;
57
57
  private _pluginOption?;
58
58
  private _playerConfig;
59
+ private _puOptions?;
59
60
  private _video;
60
61
  private _spinner;
61
62
  private _toast;
@@ -1,3 +1,4 @@
1
+ import { IOnMediaRecordHandle } from "src/utils/media";
1
2
  import { IPluginEvent, IPluginEventMap, Plugin } from "./types";
2
3
  import { IPuOption } from "src/main";
3
4
  interface IVideoPluginEvent extends IPluginEvent {
@@ -48,11 +49,12 @@ declare class VideoPlugin extends Plugin<HTMLDivElement, IVideoPluginEventMap> {
48
49
  pause(): void;
49
50
  screenshot(): Promise<{
50
51
  blob: Blob | null;
51
- download(): void;
52
+ fileName: string;
53
+ download(fileNameCaller?: string | undefined): void;
52
54
  } | undefined>;
53
55
  private _genFileName;
54
56
  recordStart(): void;
55
- recordStop(onRecordInfo?: (data: Blob, cancelAutoDownload: () => void) => void): void;
57
+ recordStop(onRecordInfo?: IOnMediaRecordHandle): void;
56
58
  rotate(degStep: number): void;
57
59
  beforeDestroy(): void;
58
60
  }
@@ -1,6 +1,16 @@
1
1
  interface IStreamProvider {
2
2
  captureStream(frameRate?: number): MediaStream;
3
3
  }
4
+ export interface IOnMediaRecordHandle {
5
+ (blob: Blob, metaInfo: {
6
+ duration: number;
7
+ startTime: number;
8
+ endTime: number;
9
+ fileName: string;
10
+ }, cancelAutoDownload: () => {
11
+ download(fileName?: string): void;
12
+ }): boolean;
13
+ }
4
14
  interface IMediaOption {
5
15
  video?: boolean;
6
16
  audio?: boolean;
@@ -35,14 +45,16 @@ declare const media: {
35
45
  canvasToBlob: (canvas: HTMLCanvasElement) => Promise<Blob | null>;
36
46
  screenshotByCanvas: (canvas?: HTMLCanvasElement | null, fileName?: string) => Promise<{
37
47
  blob: Blob | null;
38
- download(): void;
48
+ fileName: string;
49
+ download(fileNameCaller?: string): void;
39
50
  } | undefined>;
40
51
  screenshot: (videoEl?: HTMLVideoElement | null, fileName?: string) => Promise<{
41
52
  blob: Blob | null;
42
- download(): void;
53
+ fileName: string;
54
+ download(fileNameCaller?: string): void;
43
55
  } | undefined>;
44
56
  record: (element: IStreamProvider, stream?: MediaStream | null, fileName?: string) => [(MediaRecorder | undefined)?, (MediaStream | undefined)?, ({
45
- setOnMedia(onMedia: (blob: Blob, cancelAutoDownload: () => void) => Promise<void> | void): void;
57
+ setOnMedia(onMedia: IOnMediaRecordHandle): void;
46
58
  } | undefined)?];
47
59
  getMediaDir: (option: IMediaOption) => number;
48
60
  video2Canvas: (video: HTMLVideoElement, opts: IVideo2CanvasOptions) => ICanvasControl;
@@ -1 +1,2 @@
1
- export declare const createRecord: (_mediaStream: MediaStream, fileName: string, isDownload: (blob: Blob) => Promise<boolean>) => MediaRecorder;
1
+ import { IOnMediaRecordHandle } from "./media";
2
+ export declare const createRecord: (_mediaStream: MediaStream, fileName: string, isDownload: IOnMediaRecordHandle) => MediaRecorder;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@besovideo/webrtc-player",
3
- "version": "0.8.95",
3
+ "version": "0.8.97",
4
4
  "description": "@besovideo/webrtc-player desc",
5
5
  "type": "module",
6
6
  "types": "./dist/types/main.d.ts",