expo-libvlc-player
v7.0.36
Published
LibVLC Player for Expo
Downloads
5,609
Maintainers
Readme
Supported versions
| Platform | Version | | -------------------- | ------- | | React Native | 0.83 | | Android / Android TV | 7+ | | iOS / Apple TV | 15.1+ |
Installation
npm install expo-libvlc-playerBare React Native projects
For bare React Native projects, you must ensure that you have installed and configured the expo package.
Configure for Android
No additional configuration necessary.
Configure for iOS
Run npx pod-install after installing the npm package.
Configure for TV
Set the EXPO_TV environment variable, and run prebuild to make the TV modifications to the project.
EXPO_TV=1 npx expo prebuild --cleanConfiguration in app config
You can configure expo-libvlc-player using its built-in config plugin if you use config plugins in your project.
Example app.json with config plugin
{
"expo": {
"plugins": [
[
"expo-libvlc-player",
{
"localNetworkPermission": "Allow $(PRODUCT_NAME) to access your local network",
"supportsPictureInPicture": true
}
]
]
}
}Configurable properties
| Name | Description | Default |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| localNetworkPermission | A string to set the NSLocalNetworkUsageDescription permission message on iOS | "Allow $(PRODUCT_NAME) to access your local network" |
| supportsPictureInPicture | A boolean value to enable Picture-in-Picture (PiP) on Android and iOS. If true, it adds the android:supportsPictureInPicture property on Android and the audio key to the UIBackgroundModes array in the Info.plist file on iOS. If false, it removes the property on Android and the key on iOS. When undefined, the configuration is not modified | undefined |
Usage
import { LibVlcPlayerView } from "expo-libvlc-player";
const BIG_BUCK_BUNNY =
"https://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_720p_h264.mov";
return <LibVlcPlayerView source={BIG_BUCK_BUNNY} />;Trigger the local network privacy alert on iOS:
import LibVlcPlayerModule from "expo-libvlc-player";
await LibVlcPlayerModule.triggerNetworkAlert();Check for Picture-in-Picture (PiP) support:
import LibVlcPlayerModule from "expo-libvlc-player";
LibVlcPlayerModule.isPictureInPictureSupported();See the Example App for additional usage.
Module methods
| Method | Description | Returns |
| ------------------------------- | ----------------------------------------------------------- | --------------- |
| triggerNetworkAlert() | Attempts to trigger the local network privacy alert on iOS | Promise<void> |
| isPictureInPictureSupported() | Checks whether the device supports Picture-in-Picture (PiP) | boolean |
View methods
| Method | Description | Returns |
| ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------- |
| play() | Starts playback of the current player | Promise<void> |
| pause() | Pauses playback of the current player | Promise<void> |
| stop() | Stops playback of the current player | Promise<void> |
| seek(value: number, type?: "time" \| "position") | Sets the time or position of the current player. Value must be a number equal or greater than 0 and type defaults to "time" | Promise<void> |
| record(path?: string) | Starts or stops recording the current media. Path must be a valid directory or undefined to stop recording | Promise<void> |
| snapshot(path: string) | Takes a snapshot of the current media. Path must be a valid directory | Promise<void> |
| postAction(action: 1 \| 2) | Posts an answer to a dialog. Action must be either 1 or 2 | Promise<void> |
| postLogin(username: string, password: string, store?: boolean) | Posts a username and password to a login dialog. Username can't be empty, password can be empty and if true, store the credentials | Promise<void> |
| dismiss() | Dismisses a dialog | Promise<void> |
| startPictureInPicture() | Enters Picture-in-Picture (PiP) mode. Config plugin has to be configured for Picture-in-Picture (PiP) to work | Promise<void> |
| stopPictureInPicture() | Exits Picture-in-Picture (PiP) mode on iOS | Promise<void> |
View props
The LibVlcPlayerView extends React Native ViewProps and implements the following:
| Prop | Description | Default |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------- | ----------- |
| source | Sets the source of the media to be played. Set to null to release the player | |
| options | Sets the options to initialize the media with. See the VideoLAN Wiki for more | [] |
| tracks | Sets the player audio, video and subtitle tracks. See Tracks for more | undefined |
| slaves | Sets the player audio and subtitle slaves. See Slave for more | [] |
| scale | Sets the player scaling factor. Must be a number equal or greater than 0 | 0 |
| aspectRatio | Sets the container aspect ratio. Must be a valid ratio, number, or "auto" | undefined |
| contentFit | Sets how the video should be scaled to fit in the container | "contain" |
| rate | Sets the player rate. Must be a number equal or greater than 1 | 1 |
| time | Sets the initial player time. Must be a number equal or greater than 0 | 0 |
| volume | Sets the player volume. Must be a number between 0 and 100 | 100 |
| mute | Sets the player volume to 0 when true and previous value is restored when false | false |
| audioMixingMode | Determines how the player will interact with other audio in the system | "auto" |
| repeat | Determines whether the media should repeat once ended | false |
| autoplay | Determines whether the media should autoplay once created | true |
| pictureInPicture | Determines whether the player should allow Picture-in-Picture (PiP) mode | false |
Callback props
| Prop | Description | Payload |
| ------------------------- | ------------------------------------------------------------ | ----------------------------- |
| onBuffering | Called after the Buffering player event | |
| onPlaying | Called after the Playing player event | |
| onPaused | Called after the Paused player event | |
| onStopped | Called after the Stopped player event | |
| onEncounteredError | Called after the EncounteredError player event | Error |
| onDialogDisplay | Called after a dialog needs to be displayed | Dialog |
| onTimeChanged | Called after the TimeChanged player event | Time |
| onPositionChanged | Called after the PositionChanged player event | Position |
| onESAdded | Called after the ESAdded player event | MediaTracks |
| onRecordChanged | Called after the RecordChanged player event | Recording |
| onSnapshotTaken | Called after a media snapshot is taken | Snapshot |
| onFirstPlay | Called after the player first playing event | MediaInfo |
| onForeground | Called after the player enters the foreground | |
| onBackground | Called after the player enters the background | |
| onPictureInPictureStart | Called after the player enters Picture-in-Picture (PiP) mode | |
| onPictureInPictureStop | Called after the player exits Picture-in-Picture (PiP) mode | |
Module types
Tracks
interface Tracks {
audio?: number;
video?: number;
subtitle?: number;
}Slave
interface Slave {
source: string | number;
type: "audio" | "subtitle";
selected?: boolean;
}Error
interface Error {
message: string;
}Dialog
interface Dialog {
title: string;
text: string;
type: "error" | "login" | "question";
cancelText?: string;
action1Text?: string;
action2Text?: string;
}Time
interface Time {
value: number;
}Position
interface Position {
value: number;
}Track
interface Track {
id: number;
name: string;
}MediaTracks
interface MediaTracks {
audio: Track[];
video: Track[];
subtitle: Track[];
}Recording
interface Recording {
path: string | null;
isRecording: boolean;
}Snapshot
interface Snapshot {
path: string;
}MediaInfo
interface MediaInfo {
width: number;
height: number;
length: number;
seekable: boolean;
}Known issues
Black screen
On Android, the libvlcjni player detaches from the View after switching screens.
The current workaround attaches the View back to the player but causes a brief black screen.
https://code.videolan.org/videolan/vlc-android/-/issues/1495
On iOS, the VLCKit player deselects the video track after pausing in the background.
The current workaround selects the video track back but causes a brief black screen.
https://code.videolan.org/videolan/VLCKit/-/issues/743
Audio delay
On iOS, the VLCKit player experiences a small audio delay when resuming or muting media playback.
This might be related to the internal clock used by the library core causing inaccurate time values.
https://code.videolan.org/videolan/VLCKit/-/issues/233
Local network
On iOS, the VLCKit player seems to interact with the local network when playing media from external sources.
A clear message must be provided to the NSLocalNetworkUsageDescription key in the Info.plist file.
https://developer.apple.com/documentation/technotes/tn3179-understanding-local-network-privacy
Disclaimer
This project is not affiliated with, endorsed by, or officially supported by VideoLAN. The VLC icon is trademark of VideoLAN and is used here solely to indicate compatibility with the following LibVLC bindings:
libvlcjnifor Android / Android TVVLCKitfor iOS / Apple TV
For official VLC products and support, please visit videolan.org.
Credits
This library is inspired by existing projects such as react-native-vlc-media-player and expo-video.
Contributing
Contributions are always welcome. Please raise any issues or fix them by creating a pull request.
License
Made available under the MIT license, as found in the LICENSE file.
