vimeo_native_player 1.1.0 copy "vimeo_native_player: ^1.1.0" to clipboard
vimeo_native_player: ^1.1.0 copied to clipboard

Play Vimeo videos natively in Flutter with no WebView. Resolves any Vimeo link to a direct HLS or MP4 stream, so autoplay, captions and fullscreen work like any other native video.

example/lib/main.dart

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

void main() => runApp(const ExampleApp());

/// Demonstrates both ways to use the package: the drop-in player widget, and
/// the resolver on its own.
class ExampleApp extends StatelessWidget {
  /// Creates the example app.
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'vimeo_native_player',
      theme: ThemeData(
        colorSchemeSeed: Colors.teal,
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

/// The example's single screen.
class HomePage extends StatefulWidget {
  /// Creates the home page.
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final TextEditingController _urlField = TextEditingController(
    text: 'https://vimeo.com/76979871',
  );

  String _url = 'https://vimeo.com/76979871';
  VimeoVideo? _video;
  String? _error;

  void _play() {
    final input = _urlField.text.trim();
    setState(() {
      _error = VimeoUrl.isVimeo(input) ? null : 'Not a Vimeo video link.';
      _video = null;
      if (_error == null) _url = input;
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('vimeo_native_player')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          TextField(
            controller: _urlField,
            decoration: InputDecoration(
              labelText: 'Vimeo URL',
              border: const OutlineInputBorder(),
              errorText: _error,
              suffixIcon: IconButton(
                icon: const Icon(Icons.play_arrow),
                onPressed: _play,
              ),
            ),
            onSubmitted: (_) => _play(),
          ),
          const SizedBox(height: 16),

          // The player. Autoplay works with sound because playback is native.
          AspectRatio(
            aspectRatio: 16 / 9,
            child: VimeoNativePlayer(
              key: ValueKey(_url),
              url: _url,
              onResolved: (video) => setState(() => _video = video),
            ),
          ),

          const SizedBox(height: 24),
          if (_video != null) _Details(video: _video!),
        ],
      ),
    );
  }
}

/// Shows the metadata the resolver returns alongside the streams.
class _Details extends StatelessWidget {
  final VimeoVideo video;

  const _Details({required this.video});

  @override
  Widget build(BuildContext context) {
    final textTheme = Theme.of(context).textTheme;

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(video.title ?? 'Untitled', style: textTheme.titleLarge),
        if (video.owner?.name != null)
          Text('by ${video.owner!.name}', style: textTheme.bodyMedium),
        const SizedBox(height: 12),
        _row('Duration', '${video.duration}'),
        _row('Size', '${video.width}×${video.height} @ ${video.fps}fps'),
        _row('HLS streams', '${video.hlsStreams.length} (one per CDN)'),
        _row(
            'Progressive', '${video.progressiveStreams.length} MP4 renditions'),
        _row('Live', '${video.isLive}'),
        _row('360°', '${video.isSpatial}'),
        _row('URLs expire', '${video.expiresAt ?? "unknown"}'),
        if (video.textTracks.isNotEmpty) ...[
          const SizedBox(height: 12),
          Text('Subtitles', style: textTheme.titleMedium),
          for (final track in video.textTracks)
            Text(
              '• ${track.label} (${track.language})'
              '${track.isAutoGenerated ? " — auto-generated" : ""}',
            ),
        ],
      ],
    );
  }

  Widget _row(String label, String value) => Padding(
        padding: const EdgeInsets.symmetric(vertical: 2),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            SizedBox(
              width: 120,
              child: Text(label, style: const TextStyle(color: Colors.grey)),
            ),
            Expanded(child: Text(value)),
          ],
        ),
      );
}
4
likes
150
points
171
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Play Vimeo videos natively in Flutter with no WebView. Resolves any Vimeo link to a direct HLS or MP4 stream, so autoplay, captions and fullscreen work like any other native video.

Repository (GitHub)
View/report issues

Topics

#vimeo #video #video-player #hls #streaming

License

MIT (license)

Dependencies

chewie, flutter, http, video_player

More

Packages that depend on vimeo_native_player