Flutter Video Player : Crashing while creating a Video post of a size of 32 mb of 2k resolution

427 views Asked by At

I'm building a blogging app whereby I'm creating a post which uploads an video to a path on my backend django rest api and I am using video_player package to play the file on my flutter app.

I'm able to upload files up until 9 mb and play it successfully without issues. But now when I attempt to play after uploading a file which is 32 mb, the app crashes. Here is the error trace :

D/BufferPoolAccessor2.0(12981): bufferpool2 0x70b2b0f534b8 : 0(0 size) total buffers - 0(0 size) used buffers - 17/25 (recycle/alloc) - 6/22 (fetch/transfer)
D/BufferPoolAccessor2.0(12981): evictor expired: 1, evicted: 1
D/BufferPoolAccessor2.0(12981): bufferpool2 0x70b2b0f4ef58 : 0(0 size) total buffers - 0(0 size) used buffers - 15/25 (recycle/alloc) - 9/22 (fetch/transfer)
D/BufferPoolAccessor2.0(12981): bufferpool2 0x70b2b0eedfa8 : 0(0 size) total buffers - 0(0 size) used buffers - 19/30 (recycle/alloc) - 9/25 (fetch/transfer)
D/BufferPoolAccessor2.0(12981): evictor expired: 2, evicted: 2
D/BufferPoolAccessor2.0(12981): bufferpool2 0x70b2b0f3a6f8 : 5(40960 size) total buffers - 4(32768 size) used buffers - 22/27 (recycle/alloc) - 8/24 (fetch/transfer)
D/BufferPoolAccessor2.0(12981): bufferpool2 0x70b2b0f887b8 : 5(31457280 size) total buffers - 0(0 size) used buffers - 14/20 (recycle/alloc) - 10/20 (fetch/transfer)
D/BufferPoolAccessor2.0(12981): bufferpool2 0x70b2b0f5f6f8 : 5(31457280 size) total buffers - 0(0 size) used buffers - 15/20 (recycle/alloc) - 8/20 (fetch/transfer)
D/BufferPoolAccessor2.0(12981): evictor expired: 2, evicted: 2
D/BufferPoolAccessor2.0(12981): evictor expired: 1, evicted: 1
Lost connection to device.

Here is the code snippet for the same :

final url = Uri.parse('path to video file');
                  VideoPlayerController videocontroller =
                      VideoPlayerController.networkUrl(url);
                  videocontroller.addListener(() {
                    setState(() {
                      _hasVideo = true;
                    });
                  });
                  videocontroller.setLooping(true);
                  videocontroller.initialize();
                  setState(() {
                    _hasVideo = true;

Kindly note : _hasVideo is just a boolean field to differentiate between a image post and a video post.

Update as on 26/10/2023 :

To solve the likely issue of caching , I changed the VideoPlayerController to CachedVideoPlayerController from (https://pub.dev/packages/cached_video_player) package to check if the issue gets resolved since the package describes to resolve the caching issue. I attempted to upload a 32 mb video of 2k resolution and I'm getting the following trace which looks similar to earlier one.

D/BufferPoolAccessor2.0( 9534): evictor expired: 1, evicted: 1
D/BufferPoolAccessor2.0( 9534): bufferpool2 0x7d90ca5b8d48 : 5(31457280 size) total buffers - 3(18874368 size) used buffers - 636/643 (recycle/alloc) - 10/639 (fetch/transfer)
D/BufferPoolAccessor2.0( 9534): evictor expired: 1, evicted: 1
Lost connection to device.

1

There are 1 answers

8
Shahzeb Naqvi On

Try to use flutter_cache_manager it crashing due to the size of the video or upload video on the server then directly call through the link.

class VideoScreen extends StatefulWidget {
  @override
  _VideoScreenState createState() => _VideoScreenState();
}

class _VideoScreenState extends State<VideoScreen> {
  VideoPlayerController _controller;
  CacheManager _cacheManager;

  @override
  void initState() {
    super.initState();
    _cacheManager = CacheManager();
    _initializeVideoPlayer();
  }

  Future<void> _initializeVideoPlayer() async {
    // Video URL (replace with your video URL)
    String videoUrl = 'https://example.com/large_video.mp4';

    // Try to get the video file from the cache, or download it if not cached.
    File videoFile = await _cacheManager.getFile(videoUrl);

    // Initialize the video player with the video file.
    _controller = VideoPlayerController.file(videoFile);

    // Listen for when the video is initialized.
    _controller.initialize().then((_) {
      if (mounted) {
        setState(() {});
        _controller.play();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Large Video Playback'),
      ),
      body: Center(
        child: _controller.value.isInitialized
            ? AspectRatio(
                aspectRatio: _controller.value.aspectRatio,
                child: VideoPlayer(_controller),
              )
            : CircularProgressIndicator(), // Display a loading indicator while the video is initializing
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            if (_controller.value.isPlaying) {
              _controller.pause();
            } else {
              _controller.play();
            }
          });
        },
        child: Icon(
          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}