如何在Angular2应用程序中使用MediaRecorder对象?

25

我正在构建一个小型的Angular2应用程序,尝试使用MediaRecorder对象(https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder):

var mediaRecorder = new MediaRecorder(stream);

然而,TypeScript告诉我它找不到名为'MediaRecorder'的名称。我猜这是由于我的TypeScript配置问题,我直接从QuickStart指南(https://angular.io/docs/ts/latest/cookbook/visual-studio-2015.html)中获取。配置看起来像这样:
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  },
  "compileOnSave": true
}

我在网上看到过各种不同的配置,包括“target: es6”或“lib: es6”,还有一些模块不是“commonjs”的配置,但我是新手,不太清楚发生了什么。当我尝试更新这些值时,会出现更多错误。
有人知道我该如何使其正常工作吗?
7个回答

80

现在您可以更轻松地为MediaRecorder添加类型,只需通过npm安装即可。

npm install -D @types/dom-mediacapture-record

这将从DefinitelyTyped加载最新的类型定义。它们将自动工作,无需额外步骤。如果您对类型定义有任何改进,请随时将其贡献给DefinitelyTyped。


1
这个答案说:“这将自动工作,不需要额外的步骤”,但对我来说情况并非如此。请查看下面@jyl087的答案以及关于rootTypes的评论。 - user10706046
2
类型仅在开发期间需要,因此您应该使用命令的-D参数。您不希望在服务器上安装类型。 - vdegenne
@vdegenne 你是对的,已经在回答中添加了 -D 参数。谢谢! - Elias Meire
尽管我同意类型应该是一个npm包,但规则应该适用于第三方而不是标准dom API。类型应该通过tsconfig的libs属性来自typescript本身。 - Tiberiu C.

29

我也遇到了同样的问题,安装了dom-mediacapture-record模块后仍然存在问题。经过长时间的调试,我终于发现了MediaRecorder未被找到的原因。

我的应用程序有一个自动生成的"tsconfig.app.json"文件,其中包含以下行:

"compilerOptions": {
  "types": ["node"]
  ... }
我意识到“类型”阻止了dom-mediacapture-record模块的包含!应该将其更改为:

我意识到"types"阻止了dom-mediacapture-record模块的引用! 应该修改为:

"types": ["node", "dom-mediacapture-record"]

我觉得把这个小贴士传递出去可以帮助其他人避免抓狂数小时。


3
需要注意的是,需要配置应用程序模块中的tsconfig.app.json文件,而不是基本文件夹中的tsconfig.json。确保在类型数组中包含dom-mediacapture-record,并设置"typeRoots":["../node_modules/@types"]。 - ryebread761

26

在 TypeScript dom.lib 中支持 MediaRecorder 之前,any 可以满足懒人的需求。但这削弱了 TypeScript 的意义。

所以为什么不使用一个几乎完整的类型声明:

将其放置在环境声明文件中,例如:index.d.ts

declare interface MediaRecorderErrorEvent extends Event {
    name: string;
}

declare interface MediaRecorderDataAvailableEvent extends Event {
    data : any;
}

interface MediaRecorderEventMap {
    'dataavailable': MediaRecorderDataAvailableEvent;
    'error': MediaRecorderErrorEvent ;
    'pause': Event;
    'resume': Event;
    'start': Event;
    'stop': Event;
    'warning': MediaRecorderErrorEvent ;
}


declare class MediaRecorder extends EventTarget {

    readonly mimeType: string;
    readonly state: 'inactive' | 'recording' | 'paused';
    readonly stream: MediaStream;
    ignoreMutedMedia: boolean;
    videoBitsPerSecond: number;
    audioBitsPerSecond: number;

    ondataavailable: (event : MediaRecorderDataAvailableEvent) => void;
    onerror: (event: MediaRecorderErrorEvent) => void;
    onpause: () => void;
    onresume: () => void;
    onstart: () => void;
    onstop: () => void;

    constructor(stream: MediaStream);

    start();

    stop();

    resume();

    pause();

    isTypeSupported(type: string): boolean;

    requestData();


    addEventListener<K extends keyof MediaRecorderEventMap>(type: K, listener: (this: MediaStream, ev: MediaRecorderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;

    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;

    removeEventListener<K extends keyof MediaRecorderEventMap>(type: K, listener: (this: MediaStream, ev: MediaRecorderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;

    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;

}

是的,类型比赛很有效:

InteliJ类型自动完成

提示

通常我在tsconfig.json中配置一个文件夹,用于存放所有没有类型定义的jsAPIs

例如,对于这样的项目布局

project/
  @types <- a folder where I define my types 
    index.d.ts
  src
    ...
  ...
  tsconfig.json

我在tsconfig.json文件中写下如下内容:

{
  "compilerOptions": {
    ...
    "typeRoots": [
      "node_modules/@types",
      "./@types"
    ],
    ...
}

我按照您的描述完全设置了它 - 通过在tsconfig.json中添加@types目录和相应的typeRoots条目 - 但仍然出现“ERROR in src / app / modals / record / record.component.ts(179,25):error TS2304:找不到名称'MediaRecorder'。”也许我还漏掉了一些额外的步骤? - Derrick Miller
没有仔细查看很难说。也许您有多个tsconfig.json文件,至少对于使用angular-cli引导的项目是这种情况:https://github.com/stackblitz/angular-cli-template/blob/485e1f099cf4caa616eb753ec17014c8ffc5507e/.angular-cli.json#L18 您可以检查一下吗?typeRoutes在此处描述:https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#types-typeroots-and-types - Tiberiu C.
如果您已经配置了 baseURL,那么模块将根据该路径进行解析。在运行 tsc -p $PROJECT_DIR --traceResolution 时,您可以使用 --traceResolution 标志来跟踪它。 - Tiberiu C.
1
当然,如果配置对您不起作用,您可以在ts文件中使用三斜杠指令/// <reference path="..." />提示编译器环境声明的确切路径。 - Tiberiu C.
我按照这个解决方案操作,将index.d.ts文件添加到根目录下的@types文件夹中,并将其添加到typeRoots中。但是,在使用“new MediaRecorder(stream)”时,我收到了错误消息:“Type 'MediaRecorder' has no construct signatures.” 有什么想法吗? - wcjord
显示剩余2条评论

15

现在,您可以更加轻松地为MediaRecorder添加类型,只需通过npm安装它们。

npm install @types/dom-mediacapture-record

这将从DefinitelyTyped加载最新的类型定义。它们将自动工作,不需要任何额外的步骤。如果您对类型有任何改进,请随时将其贡献给DefinitelyTyped。

Elias Meire提出的解决方案对我来说是最好的。但是,确实需要一些额外的步骤才能使它起作用。正如在github上的此问题中所述https://github.com/Microsoft/TypeScript/issues/11420#issuecomment-341625253,您必须使用以下代码行引用它以便在代码中使用:

/// <reference types="@types/dom-mediacapture-record" />

抱歉,我不太清楚... 我应该把这个指令 /// <reference types="@types/dom-mediacapture-record" /> 放在哪里? - Vladlen Volkov
你尝试把它放在你需要使用的地方了吗? - Eric Niaina
你应该将 /// <reference types="@types/dom-mediacapture-record" /> 放在页面的第一行。 - yusuf

12

你的编译器对 MediaRecorder 对象一无所知。

只需像这样声明它:

declare var MediaRecorder: any;

2
这个解决方案的问题在于它不允许你声明一个类型为MediaRecorder的变量。反过来使用declare class Mediarecorder {}也无法访问媒体记录器的任何属性。因此,解决方案真正的方法是按照Tiberiu的建议声明完整的类型。 - balu

8
我在 Angular 9 应用中安装了 @types/dom-mediacapture-record,但是唯一解决此问题的方法是微调 tsconfig.app.json 文件,将以下类型添加到 "types" 中: "types": ["node", "dom-mediacapture-record"]。
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": ["node", "dom-mediacapture-record"]
  }

0

只需要运行npm install -D @types/dom-mediacapture-record,不需要修改tsconfig.json文件,也不需要类型、///reference或typeRoots(通常情况下这些都不是必需的...)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接