https://github.com/seel-channel/video_viewer
FLUTTER PACKAGE: Multiplatform minimalist video viewer with spectacular user experience.
https://github.com/seel-channel/video_viewer
flutter flutter-package video-player
Last synced: 4 months ago
JSON representation
FLUTTER PACKAGE: Multiplatform minimalist video viewer with spectacular user experience.
- Host: GitHub
- URL: https://github.com/seel-channel/video_viewer
- Owner: seel-channel
- License: mit
- Created: 2020-11-18T19:57:53.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2023-10-22T08:37:16.000Z (about 2 years ago)
- Last Synced: 2025-04-08T04:51:20.162Z (7 months ago)
- Topics: flutter, flutter-package, video-player
- Language: Dart
- Homepage: https://pub.dev/packages/video_viewer
- Size: 2.57 MB
- Stars: 54
- Watchers: 1
- Forks: 57
- Open Issues: 23
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# video_viewer
## My other APIs
- [Scroll Navigation](https://pub.dev/packages/scroll_navigation)
- [Helpers](https://pub.dev/packages/helpers)
## Features
- Amazing UI / UX.
- Fancy animations.
- Streaming Chat
- Custom Ads Support.
- Fully customizable.
- HLS (m3u8) format support.
- Captions (Subtitles) support.
- Cut the video (It just will show a specific time of the video)
- Easy and powerful implementation! :)
## **PREVIEW**
View the full source code in the [example](https://pub.dev/packages/video_viewer/example)

High-Quality Video Demo: https://user-images.githubusercontent.com/65832922/125377927-acb7b780-e342-11eb-950d-b80707e96341.mp4
## **INSTALLATION**
### Android
Add _android.permission.INTERNET_ and _usesCleartextTraffic_ in your **Android Manifest** file, located in `/android/app/src/main/AndroidManifest.xml`
```xml
```
### iOS
Add the following entry to your **Info.plist** file, located in `/ios/Runner/Info.plist`
```xml
NSAppTransportSecurity
NSAllowsArbitraryLoads
```
**Warning:** The video player is not functional on **iOS simulators.** An iOS device must be used during development/testing.
## **GLOBAL GESTURES**
- **One Tap:** Show or hide the overlay that contains the PlayAndPauseWidget and the ProgressBar
- **Double tap:**
- Left: Double tapping on the left side of the VideoViewer will do the **rewind**. Default 10 seconds.
- Right: Double-tapping on the right side of the VideoViewer will **forward**. Default 10 seconds.
- **Horizontal Drag:**
- Left: Making a horizontal movement to the left will make a **rewind** proportional to the distance traveled.
- Right: Making a horizontal movement to the right will make a **forward** proportional to the distance traveled.
- **Vertical Drag:**
- Up: **Increase** video **volume** proportional to the distance traveled.
- Down: **Decrease** video **volume** proportional to the distance traveled.
- **Scale Drag:** When the VideoViewer is on fullscreen and landscape mode you can zoom to video for completing the screen width.
## **SCREENSHOTS**
| Playing | Paused |
| :------------------------------------: | :-----------------------------------: |
|  |  |
#### Rewind and Forward
| Double Tap Rewind | Double Tap Forward |
| :-----------------------------------: | :------------------------------------: |
|  |  |
### Fullscreen
| Portrait | Landscape |
| :------------------------------------------------: | :-------------------------------------------------: |
|  |  |
### Settings Menu
| Principal Menu | Quality Menu |
| :------------------------------------------: | :-----------------------------------------: |
|  |  |
### Volume Bar

---
## **EXAMPLES**
### Using **VideoViewerController**
```dart
class UsingVideoControllerExample extends StatefulWidget {
UsingVideoControllerExample({Key key}) : super(key: key);
@override
_UsingVideoControllerExampleState createState() => _UsingVideoControllerExampleState();
}
class _UsingVideoControllerExampleState extends State {
final VideoViewerController controller = VideoViewerController();
@override
Widget build(BuildContext context) {
return VideoViewer(
controller: controller,
source: {
"SubRip Text": VideoSource(
video: VideoPlayerController.network(
"https://www.speechpad.com/proxy/get/marketing/samples/standard-captions-example.mp4"),
subtitle: {
"English": VideoViewerSubtitle.network(
"https://felipemurguia.com/assets/txt/WEBVTT_English.txt",
type: SubtitleType.webvtt,
),
},
)
},
);
}
VideoPlayerController getVideoPlayer() => controller.controller;
String getactiveSourceNameName() => controller.activeSourceName;
String getActiveCaption() => controller.activeCaption;
bool isFullScreen() => controller.isFullScreen;
bool isBuffering() => controller.isBuffering;
bool isPlaying() => controller.isPlaying;
}
```
### HLS Network Video **(This example only works on Android and iOS)**
```dart
class HLSVideoExample extends StatelessWidget {
const HLSVideoExample({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureBuilder>(
future: VideoSource.fromM3u8PlaylistUrl(
"https://sfux-ext.sfux.info/hls/chapter/105/1588724110/1588724110.m3u8",
formatter: (quality) => quality == "Auto" ? "Automatic" : "${quality.split("x").last}p",
),
builder: (_, data) {
return data.hasData
? VideoViewer(
source: data.data,
onFullscreenFixLandscape: true,
style: VideoViewerStyle(
thumbnail: Image.network(
"https://play-lh.googleusercontent.com/aA2iky4PH0REWCcPs9Qym2X7e9koaa1RtY-nKkXQsDVU6Ph25_9GkvVuyhS72bwKhN1P",
),
),
)
: CircularProgressIndicator();
},
);
}
}
```
### Network Video with WebVTT Subtitles
```dart
class WebVTTSubtitleVideoExample extends StatelessWidget {
const WebVTTSubtitleVideoExample({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return VideoViewer(
source: {
"WebVTT Caption": VideoSource(
video: VideoPlayerController.network(
//This video has a problem when end
"https://www.speechpad.com/proxy/get/marketing/samples/standard-captions-example.mp4",
),
subtitle: {
"English": VideoViewerSubtitle.network(
"https://felipemurguia.com/assets/txt/WEBVTT_English.txt",
),
"Spanish": VideoViewerSubtitle.network(
"https://felipemurguia.com/assets/txt/WEBVTT_Spanish.txt",
),
},
)
},
);
}
}
```
### Network Video with SubRip Subtitles
```dart
class SubRipSubtitleVideoExample extends StatelessWidget {
const SubRipSubtitleVideoExample({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final String content = '''
1
00:00:03,400 --> 00:00:06,177
In this lesson, we're going to
be talking about finance. And
2
00:00:06,177 --> 00:00:10,009
one of the most important aspects
of finance is interest.
3
00:00:10,009 --> 00:00:13,655
When I go to a bank or some
other lending institution
4
00:00:13,655 --> 00:00:17,720
to borrow money, the bank is happy
to give me that money. But then I'm
5
00:00:17,900 --> 00:00:21,480
going to be paying the bank for the
privilege of using their money. And that
6
00:00:21,660 --> 00:00:26,440
amount of money that I pay the bank is
called interest. Likewise, if I put money
7
00:00:26,620 --> 00:00:31,220
in a savings account or I purchase a
certificate of deposit, the bank just
8
00:00:31,300 --> 00:00:35,800
doesn't put my money in a little box
and leave it there until later. They take
9
00:00:35,800 --> 00:00:40,822
my money and lend it to someone
else. So they are using my money.
10
00:00:40,822 --> 00:00:44,400
The bank has to pay me for the privilege
of using my money.
11
00:00:44,400 --> 00:00:48,700
Now what makes banks
profitable is the rate
12
00:00:48,700 --> 00:00:53,330
that they charge people to use the bank's
money is higher than the rate that they
13
00:00:53,510 --> 00:01:00,720
pay people like me to use my money. The
amount of interest that a person pays or
14
00:01:00,800 --> 00:01:06,640
earns is dependent on three things. It's
dependent on how much money is involved.
15
00:01:06,820 --> 00:01:11,300
It's dependent upon the rate of interest
being paid or the rate of interest being
16
00:01:11,480 --> 00:01:17,898
charged. And it's also dependent upon
how much time is involved. If I have
17
00:01:17,898 --> 00:01:22,730
a loan and I want to decrease the amount
of interest that I'm going to pay, then
18
00:01:22,800 --> 00:01:28,040
I'm either going to have to decrease how
much money I borrow, I'm going to have
19
00:01:28,220 --> 00:01:32,420
to borrow the money over a shorter period
of time, or I'm going to have to find a
20
00:01:32,600 --> 00:01:37,279
lending institution that charges a lower
interest rate. On the other hand, if I
21
00:01:37,279 --> 00:01:41,480
want to earn more interest on my
investment, I'm going to have to invest
22
00:01:41,480 --> 00:01:46,860
more money, leave the money in the
account for a longer period of time, or
23
00:01:46,860 --> 00:01:49,970
find an institution that will pay
me a higher interest rate.
''';
return VideoViewer(
source: {
"SubRip Caption": VideoSource(
video: VideoPlayerController.network(
"https://www.speechpad.com/proxy/get/marketing/samples/standard-captions-example.mp4"),
subtitle: {
"English": VideoViewerSubtitle.content(
content,
type: SubtitleType.srt,
),
},
)
},
);
}
}
```