Skip to content

wako-app/wako-capacitor-video-player

Repository files navigation

wako-capacitor-video-player

Logo of wako

Official video player for wako

This Capacitor plugin is the official video player for wako, the media tracking application that allows you to manage and watch your favorite movies and TV shows.

The plugin uses MobileVLCKit on iOS and ExoPlayer (Media3) on Android to provide a high-quality, feature-rich video playback experience.

Installation

npm install wako-capacitor-video-player
npx cap sync

Key Features

The wako-capacitor video player offers numerous advanced features:

  • Video playback from remote URLs
  • Subtitle support with customization options
  • Automatic selection of audio tracks and subtitles based on preferred language
  • Playback controls (play, pause, seek, volume)
  • Playback rate management (speed)
  • Portrait and landscape mode support
  • Chromecast integration (Android)
  • Event listeners to customize the viewing experience
  • Customizable user interface options
  • Intuitive gesture controls for seamless user interaction

Usage Examples

Basic Player Initialization

import { WakoCapacitorVideoPlayer } from 'wako-capacitor-video-player';

// Simple initialization
WakoCapacitorVideoPlayer.initPlayer({
  url: "https://archive.org/download/big-buck-bunny-4k-60fps/BigBuckBunny4k60fps.mp4",
  title: "Big Buck Bunny MP4",
  smallTitle: "My small title",
  subtitles: [
    {
      url: "https://raw.githubusercontent.com/padraigfl/subtitle-ssa/refs/heads/master/test/dummySubs/3Lines.ssa",
      name: "My Sub FR",
    },
  ],
});

Advanced Initialization with Complete Options

import { WakoCapacitorVideoPlayer } from 'wako-capacitor-video-player';

// Initialization with advanced options
WakoCapacitorVideoPlayer.initPlayer({
  url: "https://example.com/video.mp4",
  title: "My video title",
  smallTitle: "Short description",
  subtitles: [
    {
      url: "https://example.com/subtitles-fr.vtt",
      name: "French",
      lang: "fr"
    },
    {
      url: "https://example.com/subtitles-en.vtt",
      name: "English",
      lang: "en"
    }
  ],
  preferredLocale: "fr",
  subtitleOptions: {
    foregroundColor: "rgba(255,255,255,1)",
    backgroundColor: "rgba(0,0,0,0.7)",
    fontSize: 18
  },
  displayMode: "all",
  chromecast: true,
  artwork: "https://example.com/poster.jpg",
  startAtSec: 30
});

Playback Control

// Play
WakoCapacitorVideoPlayer.play();

// Pause
WakoCapacitorVideoPlayer.pause();

// Navigation within the video
WakoCapacitorVideoPlayer.setCurrentTime({ seektime: 120 }); // Go to 2 minutes

// Volume control
WakoCapacitorVideoPlayer.setVolume({ volume: 0.5 }); // 50% volume

// Playback speed
WakoCapacitorVideoPlayer.setRate({ rate: 1.5 }); // 1.5x

Gesture Controls

The wako-capacitor video player includes intuitive touch gesture controls for an enhanced user experience:

Double Tap Gestures

  • Double tap right side: Fast-forward the video (typically 10 seconds)
  • Double tap left side: Rewind the video (typically 10 seconds)

These double tap gestures provide a quick and intuitive way for users to navigate through the video without having to interact with the traditional seek bar.

Additional Gesture Controls

  • Single tap: Show/hide the player controls
  • Swipe left/right: Seek through the video
  • Swipe up/down (right side): Adjust volume
  • Swipe up/down (left side): Adjust brightness (on supported devices)
  • Pinch gesture: Zoom in/out on the video content

Gesture controls automatically adapt to the device orientation and work seamlessly in both portrait and landscape modes, providing a consistent user experience across different viewing scenarios.

Event Handling

// Listen for play event
WakoCapacitorVideoPlayer.addListener('playerPlay', (info) => {
  console.log('Video is playing, current time:', info.currentTime);
});

// Listen for end of video event
WakoCapacitorVideoPlayer.addListener('playerEnded', (info) => {
  console.log('Playback has ended');
});

// Listen for player exit event
WakoCapacitorVideoPlayer.addListener('playerExit', (info) => {
  console.log('User exited the player');
  console.log('Current time:', info.currentTime);
  console.log('Exit requested by user:', info.dismiss);
});

Advanced Use Cases

Integration in an Ionic Angular Application

import { Component, OnInit, OnDestroy } from '@angular/core';
import { WakoCapacitorVideoPlayer } from 'wako-capacitor-video-player';
import { PluginListenerHandle } from '@capacitor/core';

@Component({
  selector: 'app-video-player',
  template: `
    <ion-content>
      <ion-card>
        <ion-card-header>
          <ion-card-title>Video Player</ion-card-title>
        </ion-card-header>
        <ion-card-content>
          <ion-item>
            <ion-label>Status: {{ isPlaying ? 'Playing' : 'Paused' }}</ion-label>
          </ion-item>
          <ion-item>
            <ion-label>Current time: {{ currentTime }} seconds</ion-label>
          </ion-item>
          <ion-button expand="block" (click)="playVideo()">Play</ion-button>
          <ion-button expand="block" (click)="pauseVideo()">Pause</ion-button>
        </ion-card-content>
      </ion-card>
    </ion-content>
  `
})
export class VideoPlayerComponent implements OnInit, OnDestroy {
  isPlaying = false;
  currentTime = 0;
  private playListener!: PluginListenerHandle;
  private pauseListener!: PluginListenerHandle;
  private exitListener!: PluginListenerHandle;

  constructor() {}

  async ngOnInit() {
    await this.initializePlayer();
    this.setupEventListeners();
  }

  async initializePlayer() {
    await WakoCapacitorVideoPlayer.initPlayer({
      url: "https://example.com/video.mp4",
      title: "My video",
      smallTitle: "Description",
      subtitles: [
        { url: "https://example.com/subtitles-fr.vtt", name: "French", lang: "fr" }
      ],
      preferredLocale: "fr"
    });
  }

  async setupEventListeners() {
    this.playListener = await WakoCapacitorVideoPlayer.addListener('playerPlay', (info) => {
      this.isPlaying = true;
      this.currentTime = info.currentTime;
    });

    this.pauseListener = await WakoCapacitorVideoPlayer.addListener('playerPause', (info) => {
      this.isPlaying = false;
      this.currentTime = info.currentTime;
    });

    this.exitListener = await WakoCapacitorVideoPlayer.addListener('playerExit', (info) => {
      this.isPlaying = false;
      this.currentTime = info.currentTime;
    });
  }

  async playVideo() {
    await WakoCapacitorVideoPlayer.play();
  }

  async pauseVideo() {
    await WakoCapacitorVideoPlayer.pause();
  }

  ngOnDestroy() {
    // Clean up event listeners
    if (this.playListener) this.playListener.remove();
    if (this.pauseListener) this.pauseListener.remove();
    if (this.exitListener) this.exitListener.remove();
  }
}

Managing Multiple Audio Tracks and Subtitles

import { WakoCapacitorVideoPlayer } from 'wako-capacitor-video-player';

// Initialization with multiple audio track and subtitle options
WakoCapacitorVideoPlayer.initPlayer({
  url: "https://example.com/film.mp4",
  title: "Multi-language film",
  subtitles: [
    { url: "https://example.com/subtitles-fr.vtt", name: "French", lang: "fr" },
    { url: "https://example.com/subtitles-en.vtt", name: "English", lang: "en" },
    { url: "https://example.com/subtitles-es.vtt", name: "Spanish", lang: "es" },
    { url: "https://example.com/subtitles-de.vtt", name: "German", lang: "de" }
  ],
  preferredLocale: "fr", // Automatic selection of French track if available
});

// Listen for track changes
WakoCapacitorVideoPlayer.addListener('playerTracksChanged', (info) => {
  console.log('Current audio track:', info.audioTrack);
  console.log('Current subtitle track:', info.subtitleTrack);
});

User Interface Customization

Specific Display Modes

// Portrait mode only
WakoCapacitorVideoPlayer.initPlayer({
  url: "https://example.com/video-portrait.mp4",
  title: "Portrait Mode",
  displayMode: "portrait"
});

// Landscape mode only
WakoCapacitorVideoPlayer.initPlayer({
  url: "https://example.com/video-landscape.mp4",
  title: "Landscape Mode",
  displayMode: "landscape"
});

Chromecast Integration (Android)

The Chromecast feature allows users to stream video content to a Chromecast-compatible device:

WakoCapacitorVideoPlayer.initPlayer({
  url: "https://example.com/video-hd.mp4",
  title: "HD Movie",
  smallTitle: "HD Streaming",
  chromecast: true,
  artwork: "https://example.com/poster.jpg" // Image displayed on Chromecast screen
});

Platform-Specific Capabilities

Android

  • Based on ExoPlayer (Media3) for optimized video playback
  • Full Chromecast support
  • Interface customization with title and subtitle
  • Artwork for Chromecast sessions

iOS

  • Built with MobileVLCKit for powerful and flexible playback
  • Native interface adapted to Apple standards
  • Support for specific orientation modes
  • Performance optimization for iOS devices

Optimization Tips

  1. Subtitle preloading: Ensure subtitle files are available before initializing the player
  2. Adaptive video format: Use formats like HLS or DASH for network bandwidth adaptation
  3. Memory management: Call stopAllPlayers() or exitPlayer() when you no longer need the player
  4. Local storage: For frequently watched videos, consider caching them locally

FAQ

Q: How can I implement a playback resume mechanism? A: Use addListener('playerExit') to save the position with getCurrentTime(), then use startAtSec when reinitializing.

Q: Can I customize the player controls? A: Controls are natively managed by the platform. You can show/hide them with showControls but not customize them.

Q: How do I handle videos with DRM? A: The plugin supports URLs with standard DRM protection, but specific configurations may be necessary depending on the DRM system.

Security and Permissions

The plugin requires certain permissions to function properly:

Android

  • INTERNET for online content playback
  • ACCESS_NETWORK_STATE for connectivity detection

iOS

  • No specific permissions required beyond the standard application capabilities

The wako-capacitor video player is actively maintained and optimized to offer the best possible viewing experience, while seamlessly integrating into the wako app ecosystem.

API

echo(...)

echo(options: capEchoOptions) => Promise<capVideoPlayerResult>

Echo

Param Type
options capEchoOptions

Returns: Promise<capVideoPlayerResult>


initPlayer(...)

initPlayer(options: capVideoPlayerOptions) => Promise<capVideoPlayerResult>

Initialize a video player

Param Type
options capVideoPlayerOptions

Returns: Promise<capVideoPlayerResult>


isPlaying()

isPlaying() => Promise<capVideoPlayerResult>

Return if the video is playing

Returns: Promise<capVideoPlayerResult>


play()

play() => Promise<capVideoPlayerResult>

Play the current video

Returns: Promise<capVideoPlayerResult>


pause()

pause() => Promise<capVideoPlayerResult>

Pause the current video

Returns: Promise<capVideoPlayerResult>


getDuration()

getDuration() => Promise<capVideoPlayerResult>

Get the duration of the current video

Returns: Promise<capVideoPlayerResult>


getCurrentTime()

getCurrentTime() => Promise<capVideoPlayerResult>

Get the current time of the current video

Returns: Promise<capVideoPlayerResult>


setCurrentTime(...)

setCurrentTime(options: capVideoTimeOptions) => Promise<capVideoPlayerResult>

Set the current time to seek the current video to

Param Type
options capVideoTimeOptions

Returns: Promise<capVideoPlayerResult>


getVolume()

getVolume() => Promise<capVideoPlayerResult>

Get the volume of the current video

Returns: Promise<capVideoPlayerResult>


setVolume(...)

setVolume(options: capVideoVolumeOptions) => Promise<capVideoPlayerResult>

Set the volume of the current video

Param Type
options capVideoVolumeOptions

Returns: Promise<capVideoPlayerResult>


getMuted()

getMuted() => Promise<capVideoPlayerResult>

Get the muted state of the current video

Returns: Promise<capVideoPlayerResult>


setMuted(...)

setMuted(options: capVideoMutedOptions) => Promise<capVideoPlayerResult>

Set the muted state of the current video

Param Type
options capVideoMutedOptions

Returns: Promise<capVideoPlayerResult>


setRate(...)

setRate(options: capVideoRateOptions) => Promise<capVideoPlayerResult>

Set the rate of the current video

Param Type
options capVideoRateOptions

Returns: Promise<capVideoPlayerResult>


getRate()

getRate() => Promise<capVideoPlayerResult>

Get the rate of the current video

Returns: Promise<capVideoPlayerResult>


stopAllPlayers()

stopAllPlayers() => Promise<capVideoPlayerResult>

Stop all players playing

Returns: Promise<capVideoPlayerResult>


showController()

showController() => Promise<capVideoPlayerResult>

Show controller

Returns: Promise<capVideoPlayerResult>


isControllerIsFullyVisible()

isControllerIsFullyVisible() => Promise<capVideoPlayerResult>

isControllerIsFullyVisible

Returns: Promise<capVideoPlayerResult>


exitPlayer()

exitPlayer() => Promise<capVideoPlayerResult>

Exit player

Returns: Promise<capVideoPlayerResult>


addListener('playerReady', ...)

addListener(eventName: 'playerReady', listenerFunc: PlayerReady) => Promise<PluginListenerHandle>

Listen for changes in the App's active state (whether the app is in the foreground or background)

Param Type
eventName 'playerReady'
listenerFunc PlayerReady

Returns: Promise<PluginListenerHandle>

Since: 1.0.0


addListener('playerPlay', ...)

addListener(eventName: 'playerPlay', listenerFunc: PlayerPlay) => Promise<PluginListenerHandle>
Param Type
eventName 'playerPlay'
listenerFunc PlayerPlay

Returns: Promise<PluginListenerHandle>


addListener('playerPause', ...)

addListener(eventName: 'playerPause', listenerFunc: PlayerPause) => Promise<PluginListenerHandle>
Param Type
eventName 'playerPause'
listenerFunc PlayerPause

Returns: Promise<PluginListenerHandle>


addListener('playerEnded', ...)

addListener(eventName: 'playerEnded', listenerFunc: PlayerEnded) => Promise<PluginListenerHandle>
Param Type
eventName 'playerEnded'
listenerFunc PlayerEnded

Returns: Promise<PluginListenerHandle>


addListener('playerExit', ...)

addListener(eventName: 'playerExit', listenerFunc: PlayerExit) => Promise<PluginListenerHandle>
Param Type
eventName 'playerExit'
listenerFunc PlayerExit

Returns: Promise<PluginListenerHandle>


addListener('playerTracksChanged', ...)

addListener(eventName: 'playerTracksChanged', listenerFunc: PlayerTracksChanged) => Promise<PluginListenerHandle>
Param Type
eventName 'playerTracksChanged'
listenerFunc PlayerTracksChanged

Returns: Promise<PluginListenerHandle>


Interfaces

capVideoPlayerResult

Prop Type Description
result boolean result set to true when successful else false
method string method name
value any value returned
message string message string

capEchoOptions

Prop Type Description
value string String to be echoed

capVideoPlayerOptions

Prop Type Description
url string The url of the video to play
subtitles { url: string; name?: string; lang?: string; }[] The subtitle(s) associated with the video as an array of objects Each object must contain: - url: the url of the subtitle file (required) - name: the name of the subtitle (optional) - lang: the language of the subtitle (optional)
preferredLocale string The default audio language to select, if not found will select the subtitle with the same language if available
subtitleOptions SubTitleOptions SubTitle Options
displayMode string Display Mode ["all", "portrait", "landscape"] (iOS, Android) default: "all"
componentTag string Component Tag or DOM Element Tag (React app)
title string Title shown in the player (Android) by Manuel García Marín (https://github.com/PhantomPainX)
smallTitle string Subtitle shown below the title in the player (Android) by Manuel García Marín (https://github.com/PhantomPainX)
chromecast boolean Chromecast enable/disable (Android) by Manuel García Marín (https://github.com/PhantomPainX) default: true
artwork string Artwork url to be shown in Chromecast player by Manuel García Marín (https://github.com/PhantomPainX) default: ""
subtitleTrackId string ID of the subtitle track to select
subtitleLocale string Locale of the subtitle track to select (if subtitleTrackId not found)
audioTrackId string ID of the audio track to select
audioLocale string Locale of the audio track to select (if audioTrackId not found)
startAtSec number Start time of the video

SubTitleOptions

Prop Type Description
foregroundColor string Foreground Color in RGBA (default rgba(255,255,255,1)
backgroundColor string Background Color in RGBA (default rgba(0,0,0,1)
fontSize number Font Size in pixels (default 16)

capVideoTimeOptions

Prop Type Description
seektime number Video time value you want to seek to

capVideoVolumeOptions

Prop Type Description
volume number Volume value between [0 - 1]

capVideoMutedOptions

Prop Type Description
muted boolean Muted value

capVideoRateOptions

Prop Type Description
rate number Rate value

PluginListenerHandle

Prop Type
remove () => Promise<void>

capVideoListener

Prop Type Description
currentTime number Video current time when listener trigerred

capExitListener

Prop Type Description
dismiss boolean Dismiss value true or false
currentTime number Video current time when listener trigerred

TracksChangedInfo

Prop Type
fromPlayerId string
audioTrack TrackInfo
subtitleTrack TrackInfo

TrackInfo

Prop Type
id string
language string
label string
codecs string
bitrate number
channelCount number
sampleRate number
containerMimeType string
sampleMimeType string

Type Aliases

PlayerReady

(event: capVideoListener): void

PlayerPlay

(event: capVideoListener): void

PlayerPause

(event: capVideoListener): void

PlayerEnded

(event: capVideoListener): void

PlayerExit

(event: capExitListener): void

PlayerTracksChanged

(event: TracksChangedInfo): void

About

A capacitor video player for wako.app

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors