@vonage/media-processor 1.0.1 → 1.1.3

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.
@@ -1209,7 +1209,7 @@ class EmptyOptional extends Optional {
1209
1209
  return null;
1210
1210
  }
1211
1211
  }
1212
- const version = "1.0.1";
1212
+ const version = "1.1.3";
1213
1213
  let _metadata;
1214
1214
  function setMetadata(metadata) {
1215
1215
  _metadata = metadata;
@@ -1222,20 +1222,21 @@ class ReportBuilder {
1222
1222
  const metadata = getMetadata();
1223
1223
  this._report = {
1224
1224
  action: Optional.empty(),
1225
- applicationId: Optional.ofNullable(metadata !== void 0 ? metadata.appId : null),
1225
+ applicationId: Optional.ofNullable(metadata !== void 0 && metadata != null ? metadata.appId : null),
1226
1226
  timestamp: Date.now(),
1227
1227
  fps: Optional.empty(),
1228
1228
  framesTransformed: Optional.empty(),
1229
1229
  guid: Optional.empty(),
1230
1230
  highestFrameTransformCpu: Optional.empty(),
1231
1231
  message: Optional.empty(),
1232
- source: Optional.ofNullable(metadata !== void 0 ? metadata.sourceType : null),
1232
+ source: Optional.ofNullable(metadata !== void 0 && metadata != null ? metadata.sourceType : null),
1233
1233
  transformedFps: Optional.empty(),
1234
1234
  transformerType: Optional.empty(),
1235
1235
  variation: Optional.empty(),
1236
1236
  videoHeight: Optional.empty(),
1237
1237
  videoWidth: Optional.empty(),
1238
- version
1238
+ version,
1239
+ error: Optional.empty()
1239
1240
  };
1240
1241
  }
1241
1242
  action(action) {
@@ -1278,6 +1279,10 @@ class ReportBuilder {
1278
1279
  this._report.videoWidth = Optional.ofNullable(videoWidth);
1279
1280
  return this;
1280
1281
  }
1282
+ error(error) {
1283
+ this._report.error = Optional.ofNullable(error);
1284
+ return this;
1285
+ }
1281
1286
  build() {
1282
1287
  return this._report;
1283
1288
  }
@@ -1291,6 +1296,10 @@ const serializeReport = (report) => {
1291
1296
  class Reporter {
1292
1297
  static report(report) {
1293
1298
  return new Promise((resolve, reject) => {
1299
+ if (report.applicationId.isEmpty() || report.source.isEmpty()) {
1300
+ resolve("success");
1301
+ return;
1302
+ }
1294
1303
  let axiosInstance = axios.create();
1295
1304
  let config = {
1296
1305
  timeout: 1e4,
@@ -1351,9 +1360,392 @@ function v4(options, buf, offset) {
1351
1360
  }
1352
1361
  return stringify(rnds);
1353
1362
  }
1363
+ const anyMap = new WeakMap();
1364
+ const eventsMap = new WeakMap();
1365
+ const producersMap = new WeakMap();
1366
+ const anyProducer = Symbol("anyProducer");
1367
+ const resolvedPromise = Promise.resolve();
1368
+ const listenerAdded = Symbol("listenerAdded");
1369
+ const listenerRemoved = Symbol("listenerRemoved");
1370
+ let isGlobalDebugEnabled = false;
1371
+ function assertEventName(eventName) {
1372
+ if (typeof eventName !== "string" && typeof eventName !== "symbol") {
1373
+ throw new TypeError("eventName must be a string or a symbol");
1374
+ }
1375
+ }
1376
+ function assertListener(listener) {
1377
+ if (typeof listener !== "function") {
1378
+ throw new TypeError("listener must be a function");
1379
+ }
1380
+ }
1381
+ function getListeners(instance, eventName) {
1382
+ const events = eventsMap.get(instance);
1383
+ if (!events.has(eventName)) {
1384
+ events.set(eventName, new Set());
1385
+ }
1386
+ return events.get(eventName);
1387
+ }
1388
+ function getEventProducers(instance, eventName) {
1389
+ const key = typeof eventName === "string" || typeof eventName === "symbol" ? eventName : anyProducer;
1390
+ const producers = producersMap.get(instance);
1391
+ if (!producers.has(key)) {
1392
+ producers.set(key, new Set());
1393
+ }
1394
+ return producers.get(key);
1395
+ }
1396
+ function enqueueProducers(instance, eventName, eventData) {
1397
+ const producers = producersMap.get(instance);
1398
+ if (producers.has(eventName)) {
1399
+ for (const producer of producers.get(eventName)) {
1400
+ producer.enqueue(eventData);
1401
+ }
1402
+ }
1403
+ if (producers.has(anyProducer)) {
1404
+ const item = Promise.all([eventName, eventData]);
1405
+ for (const producer of producers.get(anyProducer)) {
1406
+ producer.enqueue(item);
1407
+ }
1408
+ }
1409
+ }
1410
+ function iterator(instance, eventNames) {
1411
+ eventNames = Array.isArray(eventNames) ? eventNames : [eventNames];
1412
+ let isFinished = false;
1413
+ let flush = () => {
1414
+ };
1415
+ let queue = [];
1416
+ const producer = {
1417
+ enqueue(item) {
1418
+ queue.push(item);
1419
+ flush();
1420
+ },
1421
+ finish() {
1422
+ isFinished = true;
1423
+ flush();
1424
+ }
1425
+ };
1426
+ for (const eventName of eventNames) {
1427
+ getEventProducers(instance, eventName).add(producer);
1428
+ }
1429
+ return {
1430
+ async next() {
1431
+ if (!queue) {
1432
+ return { done: true };
1433
+ }
1434
+ if (queue.length === 0) {
1435
+ if (isFinished) {
1436
+ queue = void 0;
1437
+ return this.next();
1438
+ }
1439
+ await new Promise((resolve) => {
1440
+ flush = resolve;
1441
+ });
1442
+ return this.next();
1443
+ }
1444
+ return {
1445
+ done: false,
1446
+ value: await queue.shift()
1447
+ };
1448
+ },
1449
+ async return(value) {
1450
+ queue = void 0;
1451
+ for (const eventName of eventNames) {
1452
+ getEventProducers(instance, eventName).delete(producer);
1453
+ }
1454
+ flush();
1455
+ return arguments.length > 0 ? { done: true, value: await value } : { done: true };
1456
+ },
1457
+ [Symbol.asyncIterator]() {
1458
+ return this;
1459
+ }
1460
+ };
1461
+ }
1462
+ function defaultMethodNamesOrAssert(methodNames) {
1463
+ if (methodNames === void 0) {
1464
+ return allEmitteryMethods;
1465
+ }
1466
+ if (!Array.isArray(methodNames)) {
1467
+ throw new TypeError("`methodNames` must be an array of strings");
1468
+ }
1469
+ for (const methodName of methodNames) {
1470
+ if (!allEmitteryMethods.includes(methodName)) {
1471
+ if (typeof methodName !== "string") {
1472
+ throw new TypeError("`methodNames` element must be a string");
1473
+ }
1474
+ throw new Error(`${methodName} is not Emittery method`);
1475
+ }
1476
+ }
1477
+ return methodNames;
1478
+ }
1479
+ const isListenerSymbol = (symbol) => symbol === listenerAdded || symbol === listenerRemoved;
1480
+ class Emittery {
1481
+ static mixin(emitteryPropertyName, methodNames) {
1482
+ methodNames = defaultMethodNamesOrAssert(methodNames);
1483
+ return (target) => {
1484
+ if (typeof target !== "function") {
1485
+ throw new TypeError("`target` must be function");
1486
+ }
1487
+ for (const methodName of methodNames) {
1488
+ if (target.prototype[methodName] !== void 0) {
1489
+ throw new Error(`The property \`${methodName}\` already exists on \`target\``);
1490
+ }
1491
+ }
1492
+ function getEmitteryProperty() {
1493
+ Object.defineProperty(this, emitteryPropertyName, {
1494
+ enumerable: false,
1495
+ value: new Emittery()
1496
+ });
1497
+ return this[emitteryPropertyName];
1498
+ }
1499
+ Object.defineProperty(target.prototype, emitteryPropertyName, {
1500
+ enumerable: false,
1501
+ get: getEmitteryProperty
1502
+ });
1503
+ const emitteryMethodCaller = (methodName) => function(...args) {
1504
+ return this[emitteryPropertyName][methodName](...args);
1505
+ };
1506
+ for (const methodName of methodNames) {
1507
+ Object.defineProperty(target.prototype, methodName, {
1508
+ enumerable: false,
1509
+ value: emitteryMethodCaller(methodName)
1510
+ });
1511
+ }
1512
+ return target;
1513
+ };
1514
+ }
1515
+ static get isDebugEnabled() {
1516
+ if (typeof process !== "object") {
1517
+ return isGlobalDebugEnabled;
1518
+ }
1519
+ const { env } = process || { env: {} };
1520
+ return env.DEBUG === "emittery" || env.DEBUG === "*" || isGlobalDebugEnabled;
1521
+ }
1522
+ static set isDebugEnabled(newValue) {
1523
+ isGlobalDebugEnabled = newValue;
1524
+ }
1525
+ constructor(options = {}) {
1526
+ anyMap.set(this, new Set());
1527
+ eventsMap.set(this, new Map());
1528
+ producersMap.set(this, new Map());
1529
+ this.debug = options.debug || {};
1530
+ if (this.debug.enabled === void 0) {
1531
+ this.debug.enabled = false;
1532
+ }
1533
+ if (!this.debug.logger) {
1534
+ this.debug.logger = (type, debugName, eventName, eventData) => {
1535
+ eventData = JSON.stringify(eventData);
1536
+ if (typeof eventName === "symbol") {
1537
+ eventName = eventName.toString();
1538
+ }
1539
+ const currentTime = new Date();
1540
+ const logTime = `${currentTime.getHours()}:${currentTime.getMinutes()}:${currentTime.getSeconds()}.${currentTime.getMilliseconds()}`;
1541
+ console.log(`[${logTime}][emittery:${type}][${debugName}] Event Name: ${eventName}
1542
+ data: ${eventData}`);
1543
+ };
1544
+ }
1545
+ }
1546
+ logIfDebugEnabled(type, eventName, eventData) {
1547
+ if (Emittery.isDebugEnabled || this.debug.enabled) {
1548
+ this.debug.logger(type, this.debug.name, eventName, eventData);
1549
+ }
1550
+ }
1551
+ on(eventNames, listener) {
1552
+ assertListener(listener);
1553
+ eventNames = Array.isArray(eventNames) ? eventNames : [eventNames];
1554
+ for (const eventName of eventNames) {
1555
+ assertEventName(eventName);
1556
+ getListeners(this, eventName).add(listener);
1557
+ this.logIfDebugEnabled("subscribe", eventName, void 0);
1558
+ if (!isListenerSymbol(eventName)) {
1559
+ this.emit(listenerAdded, { eventName, listener });
1560
+ }
1561
+ }
1562
+ return this.off.bind(this, eventNames, listener);
1563
+ }
1564
+ off(eventNames, listener) {
1565
+ assertListener(listener);
1566
+ eventNames = Array.isArray(eventNames) ? eventNames : [eventNames];
1567
+ for (const eventName of eventNames) {
1568
+ assertEventName(eventName);
1569
+ getListeners(this, eventName).delete(listener);
1570
+ this.logIfDebugEnabled("unsubscribe", eventName, void 0);
1571
+ if (!isListenerSymbol(eventName)) {
1572
+ this.emit(listenerRemoved, { eventName, listener });
1573
+ }
1574
+ }
1575
+ }
1576
+ once(eventNames) {
1577
+ return new Promise((resolve) => {
1578
+ const off = this.on(eventNames, (data2) => {
1579
+ off();
1580
+ resolve(data2);
1581
+ });
1582
+ });
1583
+ }
1584
+ events(eventNames) {
1585
+ eventNames = Array.isArray(eventNames) ? eventNames : [eventNames];
1586
+ for (const eventName of eventNames) {
1587
+ assertEventName(eventName);
1588
+ }
1589
+ return iterator(this, eventNames);
1590
+ }
1591
+ async emit(eventName, eventData) {
1592
+ assertEventName(eventName);
1593
+ this.logIfDebugEnabled("emit", eventName, eventData);
1594
+ enqueueProducers(this, eventName, eventData);
1595
+ const listeners = getListeners(this, eventName);
1596
+ const anyListeners = anyMap.get(this);
1597
+ const staticListeners = [...listeners];
1598
+ const staticAnyListeners = isListenerSymbol(eventName) ? [] : [...anyListeners];
1599
+ await resolvedPromise;
1600
+ await Promise.all([
1601
+ ...staticListeners.map(async (listener) => {
1602
+ if (listeners.has(listener)) {
1603
+ return listener(eventData);
1604
+ }
1605
+ }),
1606
+ ...staticAnyListeners.map(async (listener) => {
1607
+ if (anyListeners.has(listener)) {
1608
+ return listener(eventName, eventData);
1609
+ }
1610
+ })
1611
+ ]);
1612
+ }
1613
+ async emitSerial(eventName, eventData) {
1614
+ assertEventName(eventName);
1615
+ this.logIfDebugEnabled("emitSerial", eventName, eventData);
1616
+ const listeners = getListeners(this, eventName);
1617
+ const anyListeners = anyMap.get(this);
1618
+ const staticListeners = [...listeners];
1619
+ const staticAnyListeners = [...anyListeners];
1620
+ await resolvedPromise;
1621
+ for (const listener of staticListeners) {
1622
+ if (listeners.has(listener)) {
1623
+ await listener(eventData);
1624
+ }
1625
+ }
1626
+ for (const listener of staticAnyListeners) {
1627
+ if (anyListeners.has(listener)) {
1628
+ await listener(eventName, eventData);
1629
+ }
1630
+ }
1631
+ }
1632
+ onAny(listener) {
1633
+ assertListener(listener);
1634
+ this.logIfDebugEnabled("subscribeAny", void 0, void 0);
1635
+ anyMap.get(this).add(listener);
1636
+ this.emit(listenerAdded, { listener });
1637
+ return this.offAny.bind(this, listener);
1638
+ }
1639
+ anyEvent() {
1640
+ return iterator(this);
1641
+ }
1642
+ offAny(listener) {
1643
+ assertListener(listener);
1644
+ this.logIfDebugEnabled("unsubscribeAny", void 0, void 0);
1645
+ this.emit(listenerRemoved, { listener });
1646
+ anyMap.get(this).delete(listener);
1647
+ }
1648
+ clearListeners(eventNames) {
1649
+ eventNames = Array.isArray(eventNames) ? eventNames : [eventNames];
1650
+ for (const eventName of eventNames) {
1651
+ this.logIfDebugEnabled("clear", eventName, void 0);
1652
+ if (typeof eventName === "string" || typeof eventName === "symbol") {
1653
+ getListeners(this, eventName).clear();
1654
+ const producers = getEventProducers(this, eventName);
1655
+ for (const producer of producers) {
1656
+ producer.finish();
1657
+ }
1658
+ producers.clear();
1659
+ } else {
1660
+ anyMap.get(this).clear();
1661
+ for (const listeners of eventsMap.get(this).values()) {
1662
+ listeners.clear();
1663
+ }
1664
+ for (const producers of producersMap.get(this).values()) {
1665
+ for (const producer of producers) {
1666
+ producer.finish();
1667
+ }
1668
+ producers.clear();
1669
+ }
1670
+ }
1671
+ }
1672
+ }
1673
+ listenerCount(eventNames) {
1674
+ eventNames = Array.isArray(eventNames) ? eventNames : [eventNames];
1675
+ let count = 0;
1676
+ for (const eventName of eventNames) {
1677
+ if (typeof eventName === "string") {
1678
+ count += anyMap.get(this).size + getListeners(this, eventName).size + getEventProducers(this, eventName).size + getEventProducers(this).size;
1679
+ continue;
1680
+ }
1681
+ if (typeof eventName !== "undefined") {
1682
+ assertEventName(eventName);
1683
+ }
1684
+ count += anyMap.get(this).size;
1685
+ for (const value of eventsMap.get(this).values()) {
1686
+ count += value.size;
1687
+ }
1688
+ for (const value of producersMap.get(this).values()) {
1689
+ count += value.size;
1690
+ }
1691
+ }
1692
+ return count;
1693
+ }
1694
+ bindMethods(target, methodNames) {
1695
+ if (typeof target !== "object" || target === null) {
1696
+ throw new TypeError("`target` must be an object");
1697
+ }
1698
+ methodNames = defaultMethodNamesOrAssert(methodNames);
1699
+ for (const methodName of methodNames) {
1700
+ if (target[methodName] !== void 0) {
1701
+ throw new Error(`The property \`${methodName}\` already exists on \`target\``);
1702
+ }
1703
+ Object.defineProperty(target, methodName, {
1704
+ enumerable: false,
1705
+ value: this[methodName].bind(this)
1706
+ });
1707
+ }
1708
+ }
1709
+ }
1710
+ const allEmitteryMethods = Object.getOwnPropertyNames(Emittery.prototype).filter((v) => v !== "constructor");
1711
+ Object.defineProperty(Emittery, "listenerAdded", {
1712
+ value: listenerAdded,
1713
+ writable: false,
1714
+ enumerable: true,
1715
+ configurable: false
1716
+ });
1717
+ Object.defineProperty(Emittery, "listenerRemoved", {
1718
+ value: listenerRemoved,
1719
+ writable: false,
1720
+ enumerable: true,
1721
+ configurable: false
1722
+ });
1723
+ var emittery = Emittery;
1724
+ function isErrorWithMessage(error) {
1725
+ return typeof error === "object" && error !== null && "message" in error && typeof error.message === "string";
1726
+ }
1727
+ function toErrorWithMessage(maybeError) {
1728
+ if (isErrorWithMessage(maybeError))
1729
+ return maybeError;
1730
+ try {
1731
+ return new Error(JSON.stringify(maybeError));
1732
+ } catch {
1733
+ return new Error(String(maybeError));
1734
+ }
1735
+ }
1736
+ function getErrorMessage(error) {
1737
+ return toErrorWithMessage(error).message;
1738
+ }
1739
+ var WarningType;
1740
+ (function(WarningType2) {
1741
+ WarningType2["FPS_DROP"] = "fps_drop";
1742
+ })(WarningType || (WarningType = {}));
1354
1743
  const TELEMETRY_MEDIA_TRANSFORMER_QOS_REPORT_INTERVAL = 500;
1355
- class InternalTransformer {
1356
- constructor(transformer) {
1744
+ const RATE_DROP_TO_PRECENT = 0.8;
1745
+ class InternalTransformer extends emittery {
1746
+ constructor(transformer, index) {
1747
+ super();
1748
+ this.index_ = index;
1357
1749
  this.uuid_ = v4();
1358
1750
  this.framesTransformed_ = 0;
1359
1751
  this.transformer_ = transformer;
@@ -1364,6 +1756,7 @@ class InternalTransformer {
1364
1756
  this.mediaTransformerQosReportStartTimestamp_ = 0;
1365
1757
  this.videoHeight_ = 0;
1366
1758
  this.videoWidth_ = 0;
1759
+ this.trackExpectedRate_ = -1;
1367
1760
  this.transformerType_ = "Custom";
1368
1761
  if ("getTransformerType" in transformer) {
1369
1762
  this.transformerType_ = transformer.getTransformerType();
@@ -1371,13 +1764,18 @@ class InternalTransformer {
1371
1764
  const report = new ReportBuilder().action("MediaTransformer").guid(this.uuid_).transformerType(this.transformerType_).variation("Create").build();
1372
1765
  Reporter.report(report);
1373
1766
  }
1767
+ setTrackExpectedRate(trackExpectedRate) {
1768
+ this.trackExpectedRate_ = trackExpectedRate;
1769
+ }
1374
1770
  async start(controller) {
1375
1771
  if (this.transformer_ && typeof this.transformer_.start === "function") {
1376
1772
  try {
1377
1773
  await this.transformer_.start(controller);
1378
1774
  } catch (e) {
1379
- const report = new ReportBuilder().action("MediaTransformer").guid(this.uuid_).message(Key.errors["transformer_start"]).transformerType(this.transformerType_).variation("Error").build();
1775
+ const report = new ReportBuilder().action("MediaTransformer").guid(this.uuid_).message(Key.errors["transformer_start"]).transformerType(this.transformerType_).variation("Error").error(getErrorMessage(e)).build();
1380
1776
  Reporter.report(report);
1777
+ const msg = { eventMetaData: { transformerIndex: this.index_ }, error: e, function: "start" };
1778
+ this.emit("error", msg);
1381
1779
  }
1382
1780
  }
1383
1781
  }
@@ -1398,8 +1796,10 @@ class InternalTransformer {
1398
1796
  this.mediaTransformerQosReport();
1399
1797
  }
1400
1798
  } catch (e) {
1401
- const report = new ReportBuilder().action("MediaTransformer").guid(this.uuid_).message(Key.errors["transformer_transform"]).transformerType(this.transformerType_).variation("Error").build();
1799
+ const report = new ReportBuilder().action("MediaTransformer").guid(this.uuid_).message(Key.errors["transformer_transform"]).transformerType(this.transformerType_).variation("Error").error(getErrorMessage(e)).build();
1402
1800
  Reporter.report(report);
1801
+ const msg = { eventMetaData: { transformerIndex: this.index_ }, error: e, function: "transform" };
1802
+ this.emit("error", msg);
1403
1803
  }
1404
1804
  } else {
1405
1805
  frame.close();
@@ -1414,8 +1814,10 @@ class InternalTransformer {
1414
1814
  try {
1415
1815
  await this.transformer_.flush(controller);
1416
1816
  } catch (e) {
1417
- const error = new ReportBuilder().action("MediaTransformer").guid(this.uuid_).message(Key.errors["transformer_transform"]).transformerType(this.transformerType_).variation("Error").build();
1817
+ const error = new ReportBuilder().action("MediaTransformer").guid(this.uuid_).message(Key.errors["transformer_flush"]).transformerType(this.transformerType_).variation("Error").error(getErrorMessage(e)).build();
1418
1818
  Reporter.report(error);
1819
+ const msg = { eventMetaData: { transformerIndex: this.index_ }, error: e, function: "flush" };
1820
+ this.emit("error", msg);
1419
1821
  }
1420
1822
  }
1421
1823
  this.mediaTransformerQosReport();
@@ -1430,6 +1832,10 @@ class InternalTransformer {
1430
1832
  let timeElapsed_s = (Date.now() - this.mediaTransformerQosReportStartTimestamp_) / 1e3;
1431
1833
  let fps = this.framesFromSource_ / timeElapsed_s;
1432
1834
  let transformedFps = this.framesTransformed_ / timeElapsed_s;
1835
+ if (this.trackExpectedRate_ != -1 && this.trackExpectedRate_ * RATE_DROP_TO_PRECENT > fps) {
1836
+ const msg = { eventMetaData: { transformerIndex: this.index_ }, warningType: WarningType.FPS_DROP, dropInfo: { requested: this.trackExpectedRate_, current: fps } };
1837
+ this.emit("warn", msg);
1838
+ }
1433
1839
  const qos = new ReportBuilder().action("MediaTransformer").fps(fps).transformedFps(transformedFps).framesTransformed(this.framesTransformed_).guid(this.uuid_).transformerType(this.transformerType_).videoHeight(this.videoHeight_).videoWidth(this.videoWidth_).variation("QoS").build();
1434
1840
  Reporter.report(qos);
1435
1841
  this.mediaTransformerQosReportStartTimestamp_ = 0;
@@ -1437,11 +1843,26 @@ class InternalTransformer {
1437
1843
  this.framesTransformed_ = 0;
1438
1844
  }
1439
1845
  }
1440
- class Pipeline {
1846
+ class Pipeline extends emittery {
1441
1847
  constructor(transformers) {
1848
+ super();
1442
1849
  this.transformers_ = [];
1443
- for (let transformer of transformers) {
1444
- this.transformers_.push(new InternalTransformer(transformer));
1850
+ this.trackExpectedRate_ = -1;
1851
+ for (let index = 0; index < transformers.length; index++) {
1852
+ let internalTransformer = new InternalTransformer(transformers[index], index);
1853
+ internalTransformer.on("error", (eventData) => {
1854
+ this.emit("error", eventData);
1855
+ });
1856
+ internalTransformer.on("warn", (eventData) => {
1857
+ this.emit("warn", eventData);
1858
+ });
1859
+ this.transformers_.push(internalTransformer);
1860
+ }
1861
+ }
1862
+ setTrackExpectedRate(trackExpectedRate) {
1863
+ this.trackExpectedRate_ = trackExpectedRate;
1864
+ for (let transformer of this.transformers_) {
1865
+ transformer.setTrackExpectedRate(this.trackExpectedRate_);
1445
1866
  }
1446
1867
  }
1447
1868
  async start(readable, writeable) {
@@ -1480,12 +1901,20 @@ class Pipeline {
1480
1901
  }
1481
1902
  }
1482
1903
  }
1483
- class MediaProcessor {
1904
+ class MediaProcessor extends emittery {
1484
1905
  constructor() {
1906
+ super();
1485
1907
  this.uuid_ = v4();
1908
+ this.trackExpectedRate_ = -1;
1486
1909
  const report = new ReportBuilder().action("MediaProcessor").guid(this.uuid_).variation("Create").build();
1487
1910
  Reporter.report(report);
1488
1911
  }
1912
+ setTrackExpectedRate(trackExpectedRate) {
1913
+ this.trackExpectedRate_ = trackExpectedRate;
1914
+ if (this.pipeline_) {
1915
+ this.pipeline_.setTrackExpectedRate(this.trackExpectedRate_);
1916
+ }
1917
+ }
1489
1918
  transform(readable, writable) {
1490
1919
  this.readable_ = readable;
1491
1920
  this.writable_ = writable;
@@ -1502,6 +1931,15 @@ class MediaProcessor {
1502
1931
  this.pipeline_.destroy();
1503
1932
  }
1504
1933
  this.pipeline_ = new Pipeline(this.transformers_);
1934
+ this.pipeline_.on("warn", (eventData) => {
1935
+ this.emit("warn", eventData);
1936
+ });
1937
+ this.pipeline_.on("error", (eventData) => {
1938
+ this.emit("error", eventData);
1939
+ });
1940
+ if (this.trackExpectedRate_ != -1) {
1941
+ this.pipeline_.setTrackExpectedRate(this.trackExpectedRate_);
1942
+ }
1505
1943
  this.pipeline_.start(this.readable_, this.writable_).then(() => {
1506
1944
  resolve();
1507
1945
  }).catch((e) => {
@@ -1599,4 +2037,4 @@ class MediaProcessorConnector {
1599
2037
  });
1600
2038
  }
1601
2039
  }
1602
- export { MediaProcessor, MediaProcessorConnector, isSupported, setMetadata };
2040
+ export { MediaProcessor, MediaProcessorConnector, getMetadata, isSupported, setMetadata };