You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter iOS/Android端定制视频播放(含跳过Intro)技术问询

Flutter Video Player Implementation for iOS & Android (Beginner-Friendly)

Hey there! As someone who's built similar video playback features in Flutter for both platforms, let me break down exactly how to hit all your requirements with straightforward, copy-pasteable code. Since you're new to Flutter and audio/video, I'll keep things simple and explain each part clearly.

Key Requirements Recap & Solutions

Let's tackle each of your needs one by one:

1. Hide Progress Bar, Only Allow Play/Pause

We'll use the official video_player package (the most reliable base for Flutter video) and build a custom UI—no progress bar, just a play/pause button overlayed on the video.

2. Disable Auto-Play After Loading

Good news: video_player doesn't auto-play by default. We'll just avoid calling play() until the user taps the play button.

3. Add Skip Intro Button (Jump to Specific Time)

We'll listen to the video's playback position. When the video is playing and the current time is less than your intro duration (e.g., 50 seconds), we'll show a "Skip Intro" button. Tapping it jumps the video to 50 seconds and hides the button.

4. Prevent Arbitrary Seeking

By completely omitting the progress bar and any seek controls, users can't jump to random parts of the video—only play/pause and skip the intro (if applicable).


Full Code Implementation

First, add the dependency to your pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  video_player: ^2.8.1 # Check for the latest version on pub.dev

Then, here's the complete widget code:

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

class CustomVideoPlayer extends StatefulWidget {
  final String videoUrl;
  final int introDurationSeconds; // e.g., 50 for your intro

  const CustomVideoPlayer({
    super.key,
    required this.videoUrl,
    this.introDurationSeconds = 50,
  });

  @override
  State<CustomVideoPlayer> createState() => _CustomVideoPlayerState();
}

class _CustomVideoPlayerState extends State<CustomVideoPlayer> {
  late VideoPlayerController _controller;
  bool _isPlaying = false;
  bool _showSkipButton = false;

  @override
  void initState() {
    super.initState();
    // Initialize video controller with your URL
    _controller = VideoPlayerController.network(widget.videoUrl)
      ..initialize().then((_) {
        // Video is loaded, but don't auto-play
        setState(() {});
        // Start listening to playback position to show/hide skip button
        _controller.addListener(_checkIntroStatus);
      });
  }

  void _checkIntroStatus() {
    final currentPosition = _controller.value.position.inSeconds;
    final introEnd = widget.introDurationSeconds;

    // Show skip button only if video is playing and still in intro
    setState(() {
      _showSkipButton = _controller.value.isPlaying && currentPosition < introEnd;
    });
  }

  void _togglePlayPause() {
    setState(() {
      if (_controller.value.isPlaying) {
        _controller.pause();
        _isPlaying = false;
      } else {
        _controller.play();
        _isPlaying = true;
      }
    });
  }

  void _skipIntro() {
    _controller.seekTo(Duration(seconds: widget.introDurationSeconds));
    setState(() {
      _showSkipButton = false;
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.center,
      children: [
        // Video Player
        if (_controller.value.isInitialized)
          AspectRatio(
            aspectRatio: _controller.value.aspectRatio,
            child: VideoPlayer(_controller),
          )
        else
          // Loading placeholder
          const Center(child: CircularProgressIndicator()),

        // Play/Pause Button
        IconButton(
          icon: Icon(
            _isPlaying ? Icons.pause_circle_outline : Icons.play_circle_outline,
            size: 80,
            color: Colors.white,
          ),
          onPressed: _togglePlayPause,
        ),

        // Skip Intro Button (only visible during intro and when playing)
        if (_showSkipButton)
          Positioned(
            bottom: 20,
            right: 20,
            child: ElevatedButton(
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.black54,
                foregroundColor: Colors.white,
              ),
              onPressed: _skipIntro,
              child: const Text("Skip Intro"),
            ),
          ),
      ],
    );
  }
}

// To use this widget in your app:
// CustomVideoPlayer(videoUrl: "https://your-video-url-here.mp4")

Platform-Specific Setup

iOS

Add these lines to your Info.plist (inside the <dict> tag) if you're using HTTP videos (not HTTPS):

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

Android

Add this permission to your AndroidManifest.xml (inside the <manifest> tag):

<uses-permission android:name="android.permission.INTERNET"/>

Also, ensure hardware acceleration is enabled (it's default in most cases, but add this to your <application> tag if needed):

android:hardwareAccelerated="true"

Final Notes

  • Replace https://your-video-url-here.mp4 with your actual video URL.
  • Adjust introDurationSeconds if your intro isn't 50 seconds.
  • The play/pause button is overlayed on the video—you can tweak its size/position in the IconButton widget.
  • We're properly disposing the controller in dispose() to prevent memory leaks, which is crucial for Flutter apps.

This implementation covers every requirement you listed, and it's designed to be easy for a Flutter beginner to follow and modify.

内容的提问来源于stack exchange,提问作者princeoo7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:55:55