# Creating a player


[player-api]: /player-docs/embedding/iframe-api-control-player/

You create a player through the factory received in `onKinescopeIframeAPIReady` or from [@kinescope/player-iframe-api-loader](https://docs.kinescope.com/player-docs/libraries/player-iframe-api-loader/). This page describes the factory properties and methods.

## Quick example

```js
playerFactory
  .create('player', {
    url: 'https://kinescope.io/VIDEO_ID',
    size: { width: '100%', height: 400 },
  })
  .then((player) => {
    // player is the control object. See "Controlling the player."
  })
```

## Properties

- **`Events: IframePlayerFactory.Events`** <a name="events"></a>

  The [player event enumeration](#event-data).

## Methods

- **`create(elementId: string, options: CreateOptions): Promise<IframePlayerApi>`** <a name="create"></a>

  Create a player. If the element with the `elementId` ID is not an `<iframe>`, the API replaces it with an `<iframe>`. If you pass an existing `<iframe>`, the player is embedded into it. The second argument contains the [player options](#create-options). The method returns a `Promise` with the [player control object][player-api].

  If a player with this ID already exists, the method returns the existing instance.

  > **Внимание:**

After creating the player, do not remove the element with the `elementId` ID or change the `<iframe>` URL manually. Use [`destroy`][player-api] to remove it.

  To recreate the player, wait for [`destroy`][player-api] to finish. The element with the `elementId` ID is removed from the DOM. Create another element with the same ID, then call `create`.



  <a name="CreateOptions"></a>
  **Player options** {#create-options}

  ```ts
  interface CreateOptions {
    /** Video URL */
    url: string;

    /** Size settings */
    size?: {
      /** Player width. */
      width?: number | string;
      /** Player height. */
      height?: number | string;
    };

    /** Behavior settings */
    behavior?: {
      /**
       * - `none`, `false` - do not preload the video. Only load the poster to save page resources. Default on mobile devices.
       * - `metadata`, `true` - preload the required video data. Default except on mobile devices.
       * - `auto` - let the browser and video driver choose the preload behavior.
       */
      preload?: boolean | 'none' | 'metadata' | 'auto';
      /** Remember playback time, subtitle settings, and other preferences. Default: `true`. */
      localStorage?:
        | boolean
        | {
            /**
             * - `item` - remember settings separately for each video.
             * - true | `global` - remember settings globally for all videos.
             * - false - do not remember settings.
             * Default: `global`.
             */
            quality?: 'item' | 'global' | boolean;
            /** Remember playback time. */
            time?: boolean;
            /** Remember the subtitle language. Works like `quality`. */
            textTrack?: 'item' | 'global' | boolean;
          };
      /** Control the player with the keyboard. Default: `true`. */
      keyboard?: boolean;
      /**
       * Specify a fallback when the browser does not support fullscreen mode for elements.
       * - `video` - use fullscreen mode for the video element. Used on iOS.
       * - `pseudo` - stretch the player over all other elements in the browser window.
       * Default: `video`.
       */
      fullscreenFallback?: 'video' | 'pseudo';
      /** Play video on mobile devices without entering fullscreen automatically. Default: `true`. */
      playsInline?: boolean;
      /** Loop the video. */
      loop?: boolean;
      /**
       * Start the player automatically.
       * If playback with sound fails, the player tries to start with sound muted.
       *
       * `viewable` - start automatically when the player enters the viewport.
       * Use this when the player is lower on the page and requires scrolling.
       */
      autoPlay?: boolean | 'viewable';
      /** Pause if `true`, or reset if `reset`, when another player on the page starts playing. Default: `true`. */
      autoPause?: boolean | 'reset';
      /**
       * @experimental
       *
       * `visible` - pause playback when the player is outside the viewport. */
      playback?: 'visible';
      /** Mute the player. */
      muted?: boolean;
      /** Playback speed. `1` is the normal speed. */
      playbackRate?: number;
      /**
       * Enable subtitles when the video loads.
       * - `true` - select the browser language, then the player language, then the first track.
       * - `string` - enable the track for the specified language. */
      textTrack?: boolean | string;
      /** Playlist settings. */
      playlist?: {
        /** Switch playlist videos automatically. Default: `true`. */
        autoSwitch?: boolean;
        /** Repeat the entire playlist. Default: `false`. */
        loop?: boolean;
      };
    };

    /** UI settings */
    ui?: {
      /** Player language. Defaults to the browser language or English. */
      language?: 'ru' | 'en';
      /** Show player controls. Default: `true`. */
      controls?: boolean;
      /** Show the large Play button in the center. Default: `true`. */
      mainPlayButton?: boolean;
      /** Show the playback speed button. */
      playbackRateButton?: boolean;
      /** Watermark. */
      watermark?: {
        /** Text */
        text: string;
        /**
         * - `stripes` - display in lines;
         * - `random` - display in random locations;
         * Default: `random`.
         */
        mode?: 'stripes' | 'random';
        /** Text scaling factor based on the player size. Default: `0.25`. */
        scale?: number;
        /** Show and hide duration in milliseconds. If omitted, the text remains visible. */
        displayTimeout?: number | {visible: number; hidden: number};
      };
    };

    /** Theme settings. */
    theme?: {
      subtitles?: {
        /** Base font size in em. */
        textScale?: number;
        textAlign?: 'left' | 'center';
        textLength?: 'auto' | number;
      };
      watermark: {
        default: {
          /** Watermark color as a CSS color. */
          color: string;
        };
      };
      colors: {
        /** Player color as a CSS color. For example: #4caf50. */
        primary: string;
      };
    };

    /** Player settings. */
    settings?: {
      /** Custom identifier sent with metrics. */
      externalId?: string;
    };

    /**
     * Video-specific settings: titles, subtitles, DRM, and other options.
     * The `PlaylistItemOptions` interface is described in the player method `setPlaylistItemOptions`.
     */
    playlist: PlaylistItemOptions[];
  }
  ```

  > **Информация:**

The `PlaylistItemOptions` interface for titles, subtitles, chapters, CTA, DRM, and advertising is described in [Controlling the player — setPlaylistItemOptions](https://docs.kinescope.com/player-docs/embedding/iframe-api-control-player/#setPlaylistItemOptions).



- **`on(type: IframePlayerFactory.Events, listener: Function): this`** <a name="on"></a>

  Subscribe to a factory [event](#event-data). See [Factory events](#player-factory-events).

- **`once(type: IframePlayerFactory.Events, listener: Function): this`** <a name="once"></a>

  Subscribe to a factory [event](#event-data). The [handler](#player-factory-events) runs only once.

- **`off(type: IframePlayerFactory.Events, listener: Function): this`** <a name="off"></a>

  Unsubscribe from a factory [event](#event-data).

## Factory events {#player-factory-events}

Each handler receives an [event object](#event-object) with its [data](#event-data).

### Event object {#event-object}

```ts
{
  /** Event type */
  type: IframePlayerFactory.Events;
  /** Event data. Its structure depends on the event type and may be absent. */
  data: Data;
  /** Factory. */
  target: IframePlayerFactory;
}
```

### Event enumeration {#event-data}

- **`IframePlayerFactory.Events.Created`** <a name="Events.Created"></a> — the player was created. The event data contains the [player control object][player-api].

  ```ts
  IframePlayerApi;
  ```

## Recommendations

> **Внимание:**

Do not store the player object in a global variable. Anyone can access it from the browser console.



## Next steps

- [Control the player](https://docs.kinescope.com/player-docs/embedding/iframe-api-control-player/) — instance methods and events
- [player-iframe-api-loader](https://docs.kinescope.com/player-docs/libraries/player-iframe-api-loader/) — npm loader and TypeScript types
- [Automatic connection](https://docs.kinescope.com/player-docs/embedding/iframe-api-auto-connect/) — API for an existing iframe

