How to Implement Flutter HLS Player in Video Chat Apps?

Discover how to implement an HLS player in Flutter for video chat apps. Follow our guide to integrate seamless streaming and enhance user experience in your app.

What is Flutter HLS Player?

Flutter has rapidly become a popular framework for building cross-platform mobile applications due to its efficiency and flexibility. One of the critical features many apps require is the ability to stream video content, and

HTTP Live Streaming (HLS)

is a widely-used protocol for this purpose. HLS is preferred because it allows for

adaptive bitrate streaming

, which means the video quality can adjust based on the user's internet speed, providing a seamless viewing experience.
Integrating an HLS player into a Flutter app can significantly enhance the app's multimedia capabilities. This article will guide you through the process of setting up and optimizing an HLS player in Flutter, ensuring you can provide high-quality video content to your users.

Understanding HLS Technology

HTTP Live Streaming (HLS) is a protocol developed by Apple for streaming audio and video over the internet. It works by breaking down the overall stream into a sequence of small HTTP-based file downloads, each representing a short segment of the overall content. This approach allows for adaptive bitrate streaming, which means the quality of the video can be adjusted dynamically based on the viewer's network conditions.

Benefits of Using HLS

  • Adaptive Bitrate Streaming: Ensures smooth playback by adjusting the video quality to match the user's internet speed.
  • Scalability: HLS can efficiently handle a large number of viewers, making it ideal for popular live events.
  • Wide Compatibility: Supported across many devices and platforms, including iOS, Android, smart TVs, and web browsers.

Comparison with Other Streaming Technologies:

  • DASH (Dynamic Adaptive Streaming over HTTP): Similar to HLS but developed by MPEG. It's widely supported but not as universally compatible as HLS.
  • RTMP (Real-Time Messaging Protocol): An older protocol primarily used for live streaming. It's being phased out in favor of HTTP-based protocols like HLS and DASH due to better scalability and compatibility.
HLS has become the go-to solution for streaming high-quality video content due to its robustness and flexibility.

Setting Up Flutter for HLS Streaming

To get started with

HLS streaming in Flutter

, you need to set up a new Flutter project and install the necessary dependencies. Follow the step step guide here.

Step 1. Create a New Flutter Project:

Open your terminal and run:

bash

1   flutter create hls_player
2   cd hls_player

Step 2. Install Dependencies:

For HLS streaming, the video_player plugin is commonly used. You can install it by adding the following dependency to your pubspec.yaml file:

yaml

1   dependencies:
2     flutter:
3       sdk: flutter
4     video_player: ^2.1.15

Step 3. Run flutter pub get to Install the Plugin:

bash

1   flutter pub get

Step 4. Update Android and iOS Configurations:

For Android, ensure your AndroidManifest.xml allows internet access:

xml

1   <uses-permission android:name="android.permission.INTERNET"/>
For iOS, add the following entry to your Info.plist file to permit access to network resources:

xml

1   <key>NSAppTransportSecurity</key>
2   <dict>
3     <key>NSAllowsArbitraryLoads</key>
4     <true/>
5   </dict>

Step 5. Initialize the Video Player Controller:

In your Dart code, initialize the video player controller with an HLS stream URL. Here’s an example:

dart

1   import 'package:flutter/material.dart';
2   import 'package:video_player/video_player.dart';
3
4   void main() => runApp(MyApp());
5
6   class MyApp extends StatelessWidget {
7     
8     Widget build(BuildContext context) {
9       return MaterialApp(
10         home: VideoPlayerScreen(),
11       );
12     }
13   }
14
15   class VideoPlayerScreen extends StatefulWidget {
16     
17     _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
18   }
19
20   class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
21     late VideoPlayerController _controller;
22
23     
24     void initState() {
25       super.initState();
26       _controller = VideoPlayerController.network(
27         'https://example.com/stream.m3u8'
28       )..initialize().then((_) {
29           setState(() {});
30         });
31     }
32
33     
34     void dispose() {
35       super.dispose();
36       _controller.dispose();
37     }
38
39     
40     Widget build(BuildContext context) {
41       return Scaffold(
42         appBar: AppBar(
43           title: Text('HLS Player'),
44         ),
45         body: Center(
46           child: _controller.value.isInitialized
47               ? AspectRatio(
48                   aspectRatio: _controller.value.aspectRatio,
49                   child: VideoPlayer(_controller),
50                 )
51               : CircularProgressIndicator(),
52         ),
53         floatingActionButton: FloatingActionButton(
54           onPressed: () {
55             setState(() {
56               _controller.value.isPlaying
57                   ? _controller.pause()
58                   : _controller.play();
59             });
60           },
61           child: Icon(
62             _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
63           ),
64         ),
65       );
66     }
67   }
This basic setup will get your Flutter app ready to stream HLS content. Next, we’ll look at enhancing this player with additional features.

HLS Player Implementation Guide

Basic HLS Player in Flutter Implementation Guide

To create a basic HLS player in Flutter, we will use the video_player plugin. Here’s a step-by-step guide and the necessary code snippets to implement a simple HLS player:

Step 1: Set Up Your Project

Follow the setup instructions provided in Part 1 to create a new Flutter project and install the video_player plugin.

Step 2: Create the HLS Player

In the lib directory, create a new file called video_player_screen.dart and add the following code:

dart

1   import 'package:flutter/material.dart';
2   import 'package:video_player/video_player.dart';
3
4   class VideoPlayerScreen extends StatefulWidget {
5     
6     _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
7   }
8
9   class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
10     late VideoPlayerController _controller;
11
12     
13     void initState() {
14       super.initState();
15       _controller = VideoPlayerController.network(
16         'https://example.com/stream.m3u8'
17       )..initialize().then((_) {
18           setState(() {});
19         });
20     }
21
22     
23     void dispose() {
24       _controller.dispose();
25       super.dispose();
26     }
27
28     
29     Widget build(BuildContext context) {
30       return Scaffold(
31         appBar: AppBar(
32           title: Text('HLS Player'),
33         ),
34         body: Center(
35           child: _controller.value.isInitialized
36               ? AspectRatio(
37                   aspectRatio: _controller.value.aspectRatio,
38                   child: VideoPlayer(_controller),
39                 )
40               : CircularProgressIndicator(),
41         ),
42         floatingActionButton: FloatingActionButton(
43           onPressed: () {
44             setState(() {
45               _controller.value.isPlaying ? _controller.pause() : _controller.play();
46             });
47           },
48           child: Icon(
49             _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
50           ),
51         ),
52       );
53     }
54   }

Step 3: Update main.dart to Use the New Screen

In your main.dart file, update the code to use the new VideoPlayerScreen:

dart

1   import 'package:flutter/material.dart';
2   import 'video_player_screen.dart';
3
4   void main() => runApp(MyApp());
5
6   class MyApp extends StatelessWidget {
7     
8     Widget build(BuildContext context) {
9       return MaterialApp(
10         home: VideoPlayerScreen(),
11       );
12     }
13   }
Explanation:
  • We initialize the VideoPlayerController with the URL of the HLS stream.
  • Once the controller is initialized, we update the state to reflect the new state of the controller.
  • The FloatingActionButton toggles between play and pause states.
This basic implementation should get your HLS player up and running in a Flutter app.

Enhancing the HLS Player

To enhance the functionality of your HLS player, you can add features like play, pause, seek, and fullscreen capabilities. Here’s how you can do it:

Adding Playback Controls:

Modify the VideoPlayerScreen to include a progress bar and fullscreen toggle button.

dart

1   import 'package:flutter/material.dart';
2   import 'package:video_player/video_player.dart';
3
4   class VideoPlayerScreen extends StatefulWidget {
5     
6     _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
7   }
8
9   class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
10     late VideoPlayerController _controller;
11     bool _isFullScreen = false;
12
13     
14     void initState() {
15       super.initState();
16       _controller = VideoPlayerController.network(
17         'https://example.com/stream.m3u8'
18       )..initialize().then((_) {
19           setState(() {});
20         });
21     }
22
23     
24     void dispose() {
25       _controller.dispose();
26       super.dispose();
27     }
28
29     
30     Widget build(BuildContext context) {
31       return Scaffold(
32         appBar: AppBar(
33           title: Text('HLS Player'),
34         ),
35         body: Center(
36           child: _controller.value.isInitialized
37              
38
39 ? Column(
40                   children: [
41                     AspectRatio(
42                       aspectRatio: _controller.value.aspectRatio,
43                       child: VideoPlayer(_controller),
44                     ),
45                     VideoProgressIndicator(_controller, allowScrubbing: true),
46                     Row(
47                       mainAxisAlignment: MainAxisAlignment.center,
48                       children: [
49                         IconButton(
50                           icon: Icon(
51                             _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
52                           ),
53                           onPressed: () {
54                             setState(() {
55                               _controller.value.isPlaying ? _controller.pause() : _controller.play();
56                             });
57                           },
58                         ),
59                         IconButton(
60                           icon: Icon(_isFullScreen ? Icons.fullscreen_exit : Icons.fullscreen),
61                           onPressed: () {
62                             setState(() {
63                               _isFullScreen = !_isFullScreen;
64                               if (_isFullScreen) {
65                                 SystemChrome.setEnabledSystemUIOverlays([]);
66                               } else {
67                                 SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
68                               }
69                             });
70                           },
71                         ),
72                       ],
73                     ),
74                   ],
75                 )
76               : CircularProgressIndicator(),
77         ),
78       );
79     }
80   }
Explanation:
  • Added VideoProgressIndicator to show video progress and allow scrubbing.
  • Included buttons for play/pause and fullscreen toggle.
  • Used SystemChrome.setEnabledSystemUIOverlays to toggle fullscreen mode.
By implementing these enhancements, you can provide a more user-friendly and feature-rich video player experience in your Flutter app.
Next, we will explore more advanced features and use cases in the following sections.

Advanced Features and Use Cases

Advanced Features of Flutter HLS Player

To create a more robust HLS player, you can implement advanced features like adaptive bitrate streaming, subtitles, and multiple audio tracks. These enhancements can significantly improve the user experience.

1. Implementing Adaptive Bitrate Streaming:

Adaptive bitrate streaming is a key feature of HLS, allowing the video quality to adjust based on the user's internet connection. The video_player plugin handles this automatically if the HLS stream is properly configured. Here’s how you can ensure your stream supports adaptive bitrate:
(a) Prepare Multiple Bitrate Streams: Ensure your HLS server provides different quality levels. Typically, these are specified in the .m3u8 playlist file.
(b) Example .m3u8 Playlist:
1   #EXTM3U
2   #EXT-X-STREAM-INF:BANDWIDTH=1280000,RESOLUTION=640x360
3   low/playlist.m3u8
4   #EXT-X-STREAM-INF:BANDWIDTH=2560000,RESOLUTION=1280x720
5   mid/playlist.m3u8
6   #EXT-X-STREAM-INF:BANDWIDTH=5120000,RESOLUTION=1920x1080
7   high/playlist.m3u8

2. Adding Subtitles:

To add subtitles to your HLS stream, you can use the better_player plugin, which provides more features than the basic video_player plugin.
(a). Install better_player:

yaml

1   dependencies:
2     better_player: ^0.0.75
(b). Update Your Code to Use better_player:

dart

1   import 'package:flutter/material.dart';
2   import 'package:better_player/better_player.dart';
3
4   class BetterVideoPlayerScreen extends StatefulWidget {
5     
6     _BetterVideoPlayerScreenState createState() => _BetterVideoPlayerScreenState();
7   }
8
9   class _BetterVideoPlayerScreenState extends State<BetterVideoPlayerScreen> {
10     late BetterPlayerController _betterPlayerController;
11
12     
13     void initState() {
14       super.initState();
15       BetterPlayerDataSource betterPlayerDataSource = BetterPlayerDataSource(
16         BetterPlayerDataSourceType.network,
17         'https://example.com/stream.m3u8',
18         subtitles: BetterPlayerSubtitlesSource(
19           type: BetterPlayerSubtitlesSourceType.network,
20           url: 'https://example.com/subtitles.vtt',
21         ),
22       );
23       _betterPlayerController = BetterPlayerController(
24         BetterPlayerConfiguration(),
25         betterPlayerDataSource: betterPlayerDataSource,
26       );
27     }
28
29     
30     void dispose() {
31       _betterPlayerController.dispose();
32       super.dispose();
33     }
34
35     
36     Widget build(BuildContext context) {
37       return Scaffold(
38         appBar: AppBar(
39           title: Text('Better HLS Player with Subtitles'),
40         ),
41         body: Center(
42           child: BetterPlayer(controller: _betterPlayerController),
43         ),
44       );
45     }
46   }

3. Adding Multiple Audio Tracks:

Multiple audio tracks can be added similarly through the HLS playlist and better_player configuration. Find the below example .m3u8 Playlist with Multiple Audio Tracks.
1#EXTM3U
2#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="English",LANGUAGE="en",AUTOSELECT=YES,URI="english.m3u8"
3#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",NAME="Spanish",LANGUAGE="es",AUTOSELECT=NO,URI="spanish.m3u8"
4#EXT-X-STREAM-INF:BANDWIDTH=2560000,RESOLUTION=1280x720,AUDIO="audio"
5mid/playlist.m3u8
By leveraging these advanced features, you can create a highly functional HLS player that meets diverse user needs.

Get Free 10,000 Minutes Every Months

No credit card required to start.

Performance Optimization and Best Practices of Flutter HLS Player

Ensuring optimal performance for your HLS player is crucial for providing a high-quality user experience.

1. Optimizing Video Playback Performance:

  • Use Efficient Codecs: Choose efficient video codecs like H.264 or H.265 to reduce bandwidth usage and improve playback performance.
  • Adjust Buffer Settings: Use the better_player plugin's buffer settings to manage buffering behavior:

    dart

    1 BetterPlayerConfiguration(
    2   bufferingConfiguration: BetterPlayerBufferingConfiguration(
    3     minBufferMs: 50000,
    4     maxBufferMs: 100000,
    5     bufferForPlaybackMs: 2500,
    6     bufferForPlaybackAfterRebufferMs: 5000,
    7   ),
    8 );

2. Best Practices for Efficient Streaming:

  • Use a Content Delivery Network (CDN): Distribute your video content via a CDN to reduce latency and ensure fast delivery to users worldwide.
  • Monitor Streaming Quality: Regularly monitor streaming quality and performance metrics to identify and address issues promptly.

3. Techniques for Monitoring and Improving Streaming Quality:

  • Implement Analytics: Use analytics tools to track playback performance, buffering events, and user engagement.
  • User Feedback: Collect user feedback to identify common issues and areas for improvement.
By following these best practices and optimization techniques, you can enhance the performance and reliability of your HLS player.

Troubleshooting Common Issues of Flutter HLS Player

1. Debugging Playback Issues:

  • Ensure your .m3u8 playlist and video segments are correctly formatted and accessible.
  • Check network conditions and test with different internet speeds to identify buffering issues.

2. Solutions to Compatibility Issues:

  • Test your HLS player on various devices and operating systems to ensure compatibility. Use emulators and real devices for thorough testing.

3. Community Resources:

  • Utilize community resources like Stack Overflow and Flutter forums for additional support. The Flutter and Dart documentation also provide valuable insights and troubleshooting tips.
By addressing these common questions and issues, you can enhance the robustness and user satisfaction of your Flutter HLS player.

Conclusion

Integrating an HLS player into your Flutter app significantly enhances its multimedia capabilities, providing smooth, high-quality video streaming. By following the setup and optimization steps outlined in this guide, you can leverage HLS technology's benefits, such as adaptive bitrate streaming and wide compatibility. Additionally, implementing advanced features like subtitles and multiple audio tracks ensures a comprehensive viewing experience. By optimizing performance and adhering to best practices, you can deliver a robust, user-friendly video player that meets diverse user needs.

Want to level-up your learning? Subscribe now

Subscribe to our newsletter for more tech based insights

FAQ