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.
npm install wako-capacitor-video-player
npx cap syncThe 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
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",
},
],
});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
});// 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.5xThe wako-capacitor video player includes intuitive touch gesture controls for an enhanced user experience:
- 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.
- 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.
// 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);
});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();
}
}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);
});// 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"
});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
});- Based on ExoPlayer (Media3) for optimized video playback
- Full Chromecast support
- Interface customization with title and subtitle
- Artwork for Chromecast sessions
- Built with MobileVLCKit for powerful and flexible playback
- Native interface adapted to Apple standards
- Support for specific orientation modes
- Performance optimization for iOS devices
- Subtitle preloading: Ensure subtitle files are available before initializing the player
- Adaptive video format: Use formats like HLS or DASH for network bandwidth adaptation
- Memory management: Call
stopAllPlayers()orexitPlayer()when you no longer need the player - Local storage: For frequently watched videos, consider caching them locally
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.
The plugin requires certain permissions to function properly:
INTERNETfor online content playbackACCESS_NETWORK_STATEfor connectivity detection
- 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.
echo(...)initPlayer(...)isPlaying()play()pause()getDuration()getCurrentTime()setCurrentTime(...)getVolume()setVolume(...)getMuted()setMuted(...)setRate(...)getRate()stopAllPlayers()showController()isControllerIsFullyVisible()exitPlayer()addListener('playerReady', ...)addListener('playerPlay', ...)addListener('playerPause', ...)addListener('playerEnded', ...)addListener('playerExit', ...)addListener('playerTracksChanged', ...)- Interfaces
- Type Aliases
echo(options: capEchoOptions) => Promise<capVideoPlayerResult>Echo
| Param | Type |
|---|---|
options |
capEchoOptions |
Returns: Promise<capVideoPlayerResult>
initPlayer(options: capVideoPlayerOptions) => Promise<capVideoPlayerResult>Initialize a video player
| Param | Type |
|---|---|
options |
capVideoPlayerOptions |
Returns: Promise<capVideoPlayerResult>
isPlaying() => Promise<capVideoPlayerResult>Return if the video is playing
Returns: Promise<capVideoPlayerResult>
play() => Promise<capVideoPlayerResult>Play the current video
Returns: Promise<capVideoPlayerResult>
pause() => Promise<capVideoPlayerResult>Pause the current video
Returns: Promise<capVideoPlayerResult>
getDuration() => Promise<capVideoPlayerResult>Get the duration of the current video
Returns: Promise<capVideoPlayerResult>
getCurrentTime() => Promise<capVideoPlayerResult>Get the current time of the current video
Returns: Promise<capVideoPlayerResult>
setCurrentTime(options: capVideoTimeOptions) => Promise<capVideoPlayerResult>Set the current time to seek the current video to
| Param | Type |
|---|---|
options |
capVideoTimeOptions |
Returns: Promise<capVideoPlayerResult>
getVolume() => Promise<capVideoPlayerResult>Get the volume of the current video
Returns: Promise<capVideoPlayerResult>
setVolume(options: capVideoVolumeOptions) => Promise<capVideoPlayerResult>Set the volume of the current video
| Param | Type |
|---|---|
options |
capVideoVolumeOptions |
Returns: Promise<capVideoPlayerResult>
getMuted() => Promise<capVideoPlayerResult>Get the muted state of the current video
Returns: Promise<capVideoPlayerResult>
setMuted(options: capVideoMutedOptions) => Promise<capVideoPlayerResult>Set the muted state of the current video
| Param | Type |
|---|---|
options |
capVideoMutedOptions |
Returns: Promise<capVideoPlayerResult>
setRate(options: capVideoRateOptions) => Promise<capVideoPlayerResult>Set the rate of the current video
| Param | Type |
|---|---|
options |
capVideoRateOptions |
Returns: Promise<capVideoPlayerResult>
getRate() => Promise<capVideoPlayerResult>Get the rate of the current video
Returns: Promise<capVideoPlayerResult>
stopAllPlayers() => Promise<capVideoPlayerResult>Stop all players playing
Returns: Promise<capVideoPlayerResult>
showController() => Promise<capVideoPlayerResult>Show controller
Returns: Promise<capVideoPlayerResult>
isControllerIsFullyVisible() => Promise<capVideoPlayerResult>isControllerIsFullyVisible
Returns: Promise<capVideoPlayerResult>
exitPlayer() => Promise<capVideoPlayerResult>Exit player
Returns: Promise<capVideoPlayerResult>
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(eventName: 'playerPlay', listenerFunc: PlayerPlay) => Promise<PluginListenerHandle>| Param | Type |
|---|---|
eventName |
'playerPlay' |
listenerFunc |
PlayerPlay |
Returns: Promise<PluginListenerHandle>
addListener(eventName: 'playerPause', listenerFunc: PlayerPause) => Promise<PluginListenerHandle>| Param | Type |
|---|---|
eventName |
'playerPause' |
listenerFunc |
PlayerPause |
Returns: Promise<PluginListenerHandle>
addListener(eventName: 'playerEnded', listenerFunc: PlayerEnded) => Promise<PluginListenerHandle>| Param | Type |
|---|---|
eventName |
'playerEnded' |
listenerFunc |
PlayerEnded |
Returns: Promise<PluginListenerHandle>
addListener(eventName: 'playerExit', listenerFunc: PlayerExit) => Promise<PluginListenerHandle>| Param | Type |
|---|---|
eventName |
'playerExit' |
listenerFunc |
PlayerExit |
Returns: Promise<PluginListenerHandle>
addListener(eventName: 'playerTracksChanged', listenerFunc: PlayerTracksChanged) => Promise<PluginListenerHandle>| Param | Type |
|---|---|
eventName |
'playerTracksChanged' |
listenerFunc |
PlayerTracksChanged |
Returns: Promise<PluginListenerHandle>
| 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 |
| Prop | Type | Description |
|---|---|---|
value |
string |
String to be echoed |
| 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 |
| 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) |
| Prop | Type | Description |
|---|---|---|
seektime |
number |
Video time value you want to seek to |
| Prop | Type | Description |
|---|---|---|
volume |
number |
Volume value between [0 - 1] |
| Prop | Type | Description |
|---|---|---|
muted |
boolean |
Muted value |
| Prop | Type | Description |
|---|---|---|
rate |
number |
Rate value |
| Prop | Type |
|---|---|
remove |
() => Promise<void> |
| Prop | Type | Description |
|---|---|---|
currentTime |
number |
Video current time when listener trigerred |
| Prop | Type | Description |
|---|---|---|
dismiss |
boolean |
Dismiss value true or false |
currentTime |
number |
Video current time when listener trigerred |
| Prop | Type |
|---|---|
fromPlayerId |
string |
audioTrack |
TrackInfo |
subtitleTrack |
TrackInfo |
| Prop | Type |
|---|---|
id |
string |
language |
string |
label |
string |
codecs |
string |
bitrate |
number |
channelCount |
number |
sampleRate |
number |
containerMimeType |
string |
sampleMimeType |
string |
(event: capVideoListener): void
(event: capVideoListener): void
(event: capVideoListener): void
(event: capVideoListener): void
(event: capExitListener): void
(event: TracksChangedInfo): void