pxt-microbit 5.1.26 → 5.1.27

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/built/sim.d.ts CHANGED
@@ -571,6 +571,10 @@ declare namespace pxsim {
571
571
  audioURL: string;
572
572
  recording: HTMLAudioElement;
573
573
  audioPlaying: boolean;
574
+ recordTimeoutID: any;
575
+ handleAudioPlaying: () => void;
576
+ handleAudioStopped: () => void;
577
+ initListeners: () => void;
574
578
  }
575
579
  }
576
580
  declare namespace pxsim.record {
package/built/sim.js CHANGED
@@ -2279,6 +2279,18 @@ var pxsim;
2279
2279
  constructor() {
2280
2280
  this.currentlyRecording = false;
2281
2281
  this.audioPlaying = false;
2282
+ this.handleAudioPlaying = () => {
2283
+ this.audioPlaying = true;
2284
+ };
2285
+ this.handleAudioStopped = () => {
2286
+ this.audioPlaying = false;
2287
+ };
2288
+ this.initListeners = () => {
2289
+ if (this.recording) {
2290
+ this.recording.addEventListener("play", this.handleAudioPlaying, false);
2291
+ this.recording.addEventListener("ended", this.handleAudioStopped, false);
2292
+ }
2293
+ };
2282
2294
  }
2283
2295
  }
2284
2296
  pxsim.RecordingState = RecordingState;
@@ -2286,53 +2298,102 @@ var pxsim;
2286
2298
  (function (pxsim) {
2287
2299
  var record;
2288
2300
  (function (record_1) {
2301
+ function stopRecorder(b) {
2302
+ b.recordingState.recorder.stop();
2303
+ b.recordingState.currentlyRecording = false;
2304
+ if (b.recordingState.stream.active) {
2305
+ b.recordingState.stream.getAudioTracks().forEach(track => {
2306
+ track.stop();
2307
+ track.enabled = false;
2308
+ });
2309
+ }
2310
+ }
2311
+ function populateRecording(b) {
2312
+ const blob = new Blob(b.recordingState.chunks, { type: "audio/ogg; codecs=opus" });
2313
+ b.recordingState.audioURL = window.URL.createObjectURL(blob);
2314
+ b.recordingState.recording = new Audio(b.recordingState.audioURL);
2315
+ b.recordingState.initListeners();
2316
+ b.recordingState.currentlyRecording = false;
2317
+ b.recordingState.recorder = null;
2318
+ b.recordingState.chunks = [];
2319
+ }
2289
2320
  async function record() {
2290
- //request permission is asynchronous
2291
2321
  let b = pxsim.board();
2292
- let recordingState = b.recordingState;
2293
- if (!b.recordingState.currentlyRecording) {
2294
- b.recordingState.currentlyRecording = true;
2295
- pxsim.runtime.queueDisplayUpdate();
2296
- if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
2297
- try {
2298
- recordingState.stream = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
2299
- recordingState.recorder = new MediaRecorder(recordingState.stream);
2300
- recordingState.recorder.start();
2301
- setTimeout(() => {
2302
- recordingState.recorder.stop();
2303
- pxsim.runtime.queueDisplayUpdate();
2304
- }, 4000);
2305
- recordingState.recorder.ondataavailable = (e) => {
2306
- recordingState.chunks.push(e.data);
2307
- };
2308
- recordingState.recorder.onstop = () => {
2309
- const blob = new Blob(recordingState.chunks, { type: "audio/ogg; codecs=opus" });
2310
- recordingState.audioURL = window.URL.createObjectURL(blob);
2311
- recordingState.recording = new Audio(recordingState.audioURL);
2312
- b.recordingState.currentlyRecording = false;
2313
- erase();
2314
- };
2315
- }
2316
- catch (error) {
2317
- console.log("An error occurred, could not get microphone access");
2318
- }
2322
+ if (b.recordingState.recorder) {
2323
+ b.recordingState.recorder.stop();
2324
+ clearTimeout(b.recordingState.recordTimeoutID);
2325
+ }
2326
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
2327
+ try {
2328
+ b.recordingState.stream = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
2329
+ b.recordingState.recorder = new MediaRecorder(b.recordingState.stream);
2330
+ b.recordingState.recorder.start();
2331
+ b.recordingState.currentlyRecording = true;
2332
+ pxsim.runtime.queueDisplayUpdate();
2333
+ b.recordingState.recordTimeoutID = setTimeout(() => {
2334
+ stopRecorder(b);
2335
+ pxsim.runtime.queueDisplayUpdate();
2336
+ }, 5000);
2337
+ b.recordingState.recorder.ondataavailable = (e) => {
2338
+ b.recordingState.chunks.push(e.data);
2339
+ };
2340
+ b.recordingState.recorder.onstop = () => {
2341
+ populateRecording(b);
2342
+ registerSimStop(b);
2343
+ };
2319
2344
  }
2320
- else {
2321
- console.log("getUserMedia not supported on your browser!");
2345
+ catch (error) {
2346
+ console.log("An error occurred, could not get microphone access");
2347
+ if (b.recordingState.recorder) {
2348
+ b.recordingState.recorder.stop();
2349
+ }
2350
+ b.recordingState.currentlyRecording = false;
2322
2351
  }
2323
2352
  }
2353
+ else {
2354
+ console.log("getUserMedia not supported on your browser!");
2355
+ b.recordingState.currentlyRecording = false;
2356
+ }
2324
2357
  }
2325
2358
  record_1.record = record;
2359
+ function stopAudio() {
2360
+ const b = pxsim.board();
2361
+ if (!b)
2362
+ return;
2363
+ if (b.recordingState.currentlyRecording && b.recordingState.recordTimeoutID) {
2364
+ clearTimeout(b.recordingState.recordTimeoutID);
2365
+ stopRecorder(b);
2366
+ }
2367
+ else if (b.recordingState.recording && b.recordingState.audioPlaying) {
2368
+ b.recordingState.handleAudioStopped();
2369
+ b.recordingState.recording.pause();
2370
+ b.recordingState.recording.currentTime = 0;
2371
+ }
2372
+ }
2373
+ function registerSimStop(b) {
2374
+ pxsim.AudioContextManager.onStopAll(() => {
2375
+ if (b.recordingState.recording) {
2376
+ stopAudio();
2377
+ b.recordingState.recording.removeEventListener("play", b.recordingState.handleAudioPlaying);
2378
+ b.recordingState.recording.removeEventListener("ended", b.recordingState.handleAudioStopped);
2379
+ }
2380
+ });
2381
+ }
2326
2382
  function play() {
2327
2383
  const b = pxsim.board();
2328
2384
  if (!b)
2329
2385
  return;
2330
- if (b.recordingState.recording) {
2331
- b.recordingState.recording.play();
2332
- }
2386
+ stopAudio();
2387
+ b.recordingState.audioPlaying = true;
2388
+ setTimeout(() => {
2389
+ if (b.recordingState.recording) {
2390
+ b.recordingState.recording.play();
2391
+ }
2392
+ }, 10);
2333
2393
  }
2334
2394
  record_1.play = play;
2335
2395
  function stop() {
2396
+ stopAudio();
2336
2397
  }
2337
2398
  record_1.stop = stop;
2338
2399
  function erase() {
@@ -2340,6 +2401,13 @@ var pxsim;
2340
2401
  if (!b)
2341
2402
  return;
2342
2403
  b.recordingState.chunks = [];
2404
+ if (b.recordingState.audioPlaying) {
2405
+ b.recordingState.recording.pause();
2406
+ b.recordingState.audioPlaying = false;
2407
+ b.recordingState.recording.currentTime = 0;
2408
+ }
2409
+ window.URL.revokeObjectURL(b.recordingState.audioURL);
2410
+ b.recordingState.recording = null;
2343
2411
  }
2344
2412
  record_1.erase = erase;
2345
2413
  function setMicrophoneGain(gain) {
@@ -2353,14 +2421,6 @@ var pxsim;
2353
2421
  const b = pxsim.board();
2354
2422
  if (!b)
2355
2423
  return false;
2356
- if (b.recordingState.recording) {
2357
- b.recordingState.recording.addEventListener("playing", () => {
2358
- b.recordingState.audioPlaying = true;
2359
- }, { once: true });
2360
- b.recordingState.recording.addEventListener("ended", () => {
2361
- b.recordingState.audioPlaying = false;
2362
- }, { once: true });
2363
- }
2364
2424
  return b.recordingState.audioPlaying;
2365
2425
  }
2366
2426
  record_1.audioIsPlaying = audioIsPlaying;
@@ -2368,14 +2428,16 @@ var pxsim;
2368
2428
  const b = pxsim.board();
2369
2429
  if (!b)
2370
2430
  return false;
2371
- return b.recordingState.recorder ? b.recordingState.recorder.state == "recording" : false;
2431
+ return b.recordingState.recorder ? b.recordingState.recorder.state === "recording" : false;
2372
2432
  }
2373
2433
  record_1.audioIsRecording = audioIsRecording;
2374
2434
  function audioIsStopped() {
2375
2435
  const b = pxsim.board();
2376
2436
  if (!b)
2377
2437
  return true;
2378
- return b.recordingState.recorder ? !b.recordingState.audioPlaying && b.recordingState.recorder.state == "inactive" : true;
2438
+ const isNotPlaying = !audioIsPlaying();
2439
+ const isNotRecording = !audioIsRecording();
2440
+ return b.recordingState.recording ? isNotPlaying && isNotRecording : false;
2379
2441
  }
2380
2442
  record_1.audioIsStopped = audioIsStopped;
2381
2443
  function setInputSampleRate(sampleRate) {