diff --git a/lib/mpv/mpv.dart b/lib/mpv/mpv.dart index 6371babb..ea8b2c83 100644 --- a/lib/mpv/mpv.dart +++ b/lib/mpv/mpv.dart @@ -17,7 +17,7 @@ /// import 'package:flutter_application_1/mpv/mpv.dart'; /// /// // Create a player -/// final player = MpvPlayer(); +/// final player = Player(); /// /// // Configure player properties /// await player.setProperty('hwdec', 'auto'); @@ -25,7 +25,7 @@ /// await player.setAudioPassthrough(true); /// /// // Open and play media -/// await player.open(MpvMedia('https://example.com/video.mp4')); +/// await player.open(Media('https://example.com/video.mp4')); /// /// // Listen to state changes /// player.streams.position.listen((position) { @@ -33,7 +33,7 @@ /// }); /// /// // Display video -/// MpvVideo( +/// Video( /// player: player, /// controls: (context) => MyCustomControls(), /// ) @@ -44,26 +44,26 @@ library; // Import for type alias -import 'src/models/mpv_track_selection.dart' as track_selection; +import 'src/models/track_selection.dart' as track_selection; // Player -export 'src/player/mpv_player.dart'; -export 'src/player/mpv_player_state.dart'; -export 'src/player/mpv_player_streams.dart'; -export 'src/player/mpv_player_stub.dart'; +export 'src/player/player.dart'; +export 'src/player/player_state.dart'; +export 'src/player/player_streams.dart'; +export 'src/player/player_stub.dart'; // Models -export 'src/models/mpv_media.dart'; -export 'src/models/mpv_audio_device.dart'; -export 'src/models/mpv_audio_track.dart'; -export 'src/models/mpv_subtitle_track.dart'; -export 'src/models/mpv_tracks.dart'; -export 'src/models/mpv_track_selection.dart'; -export 'src/models/mpv_log.dart'; -export 'src/models/mpv_log_level.dart'; +export 'src/models/media.dart'; +export 'src/models/audio_device.dart'; +export 'src/models/audio_track.dart'; +export 'src/models/subtitle_track.dart'; +export 'src/models/tracks.dart'; +export 'src/models/track_selection.dart'; +export 'src/models/player_log.dart'; +export 'src/models/player_log_level.dart'; // Video -export 'src/video/mpv_video.dart'; +export 'src/video/video.dart'; // Type alias for compatibility (must be after exports) -typedef MpvTrack = track_selection.MpvTrackSelection; +typedef Track = track_selection.TrackSelection; diff --git a/lib/mpv/src/models/mpv_audio_device.dart b/lib/mpv/src/models/audio_device.dart similarity index 69% rename from lib/mpv/src/models/mpv_audio_device.dart rename to lib/mpv/src/models/audio_device.dart index 4cee9845..5fc157d0 100644 --- a/lib/mpv/src/models/mpv_audio_device.dart +++ b/lib/mpv/src/models/audio_device.dart @@ -1,26 +1,26 @@ /// Represents an audio output device. -class MpvAudioDevice { +class AudioDevice { /// Unique identifier for the device. final String name; /// Human-readable description of the device. final String description; - const MpvAudioDevice({ + const AudioDevice({ required this.name, this.description = '', }); /// Default/auto audio device. - static const auto = MpvAudioDevice(name: 'auto', description: 'Auto'); + static const auto = AudioDevice(name: 'auto', description: 'Auto'); @override - String toString() => 'MpvAudioDevice($name, $description)'; + String toString() => 'AudioDevice($name, $description)'; @override bool operator ==(Object other) => identical(this, other) || - other is MpvAudioDevice && + other is AudioDevice && runtimeType == other.runtimeType && name == other.name; diff --git a/lib/mpv/src/models/mpv_audio_track.dart b/lib/mpv/src/models/audio_track.dart similarity index 84% rename from lib/mpv/src/models/mpv_audio_track.dart rename to lib/mpv/src/models/audio_track.dart index 5b8284c9..b1efe622 100644 --- a/lib/mpv/src/models/mpv_audio_track.dart +++ b/lib/mpv/src/models/audio_track.dart @@ -1,5 +1,5 @@ /// Represents an audio track in the media. -class MpvAudioTrack { +class AudioTrack { /// Unique identifier for the track. final String id; @@ -30,7 +30,7 @@ class MpvAudioTrack { /// Whether this track is forced. final bool isForced; - const MpvAudioTrack({ + const AudioTrack({ required this.id, this.title, this.language, @@ -43,10 +43,10 @@ class MpvAudioTrack { }); /// Auto-select track. - static const auto = MpvAudioTrack(id: 'auto', title: 'Auto'); + static const auto = AudioTrack(id: 'auto', title: 'Auto'); /// Disable audio. - static const off = MpvAudioTrack(id: 'no', title: 'Off'); + static const off = AudioTrack(id: 'no', title: 'Off'); /// Returns a display name for the track. String get displayName { @@ -56,12 +56,12 @@ class MpvAudioTrack { } @override - String toString() => 'MpvAudioTrack($id, $displayName)'; + String toString() => 'AudioTrack($id, $displayName)'; @override bool operator ==(Object other) => identical(this, other) || - other is MpvAudioTrack && + other is AudioTrack && runtimeType == other.runtimeType && id == other.id; diff --git a/lib/mpv/src/models/mpv_media.dart b/lib/mpv/src/models/media.dart similarity index 78% rename from lib/mpv/src/models/mpv_media.dart rename to lib/mpv/src/models/media.dart index ef74e566..2d395155 100644 --- a/lib/mpv/src/models/mpv_media.dart +++ b/lib/mpv/src/models/media.dart @@ -1,5 +1,5 @@ -/// Represents a media source for the MPV player. -class MpvMedia { +/// Represents a media source for the player. +class Media { /// The URI of the media (file path, HTTP URL, etc.). final String uri; @@ -9,19 +9,19 @@ class MpvMedia { /// Optional start position for playback. final Duration? start; - const MpvMedia( + const Media( this.uri, { this.headers, this.start, }); @override - String toString() => 'MpvMedia($uri)'; + String toString() => 'Media($uri)'; @override bool operator ==(Object other) => identical(this, other) || - other is MpvMedia && + other is Media && runtimeType == other.runtimeType && uri == other.uri && start == other.start; diff --git a/lib/mpv/src/models/mpv_track_selection.dart b/lib/mpv/src/models/mpv_track_selection.dart deleted file mode 100644 index 47399c9c..00000000 --- a/lib/mpv/src/models/mpv_track_selection.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'mpv_audio_track.dart'; -import 'mpv_subtitle_track.dart'; - -/// Represents the currently selected tracks. -class MpvTrackSelection { - /// Currently selected audio track. - final MpvAudioTrack? audio; - - /// Currently selected subtitle track. - final MpvSubtitleTrack? subtitle; - - const MpvTrackSelection({ - this.audio, - this.subtitle, - }); - - /// Creates a copy with the given fields replaced. - MpvTrackSelection copyWith({ - MpvAudioTrack? audio, - MpvSubtitleTrack? subtitle, - }) { - return MpvTrackSelection( - audio: audio ?? this.audio, - subtitle: subtitle ?? this.subtitle, - ); - } - - @override - String toString() => 'MpvTrackSelection(audio: $audio, subtitle: $subtitle)'; -} diff --git a/lib/mpv/src/models/mpv_log.dart b/lib/mpv/src/models/player_log.dart similarity index 71% rename from lib/mpv/src/models/mpv_log.dart rename to lib/mpv/src/models/player_log.dart index ce47883f..1c084570 100644 --- a/lib/mpv/src/models/mpv_log.dart +++ b/lib/mpv/src/models/player_log.dart @@ -1,9 +1,9 @@ -import 'mpv_log_level.dart'; +import 'player_log_level.dart'; -/// A log entry from the MPV player. -class MpvLog { +/// A log entry from the player. +class PlayerLog { /// The log level of this message. - final MpvLogLevel level; + final PlayerLogLevel level; /// The prefix/category of the log message (e.g., 'cplayer', 'ffmpeg'). final String prefix; @@ -11,7 +11,7 @@ class MpvLog { /// The log message text. final String text; - const MpvLog({ + const PlayerLog({ required this.level, required this.prefix, required this.text, diff --git a/lib/mpv/src/models/mpv_log_level.dart b/lib/mpv/src/models/player_log_level.dart similarity index 82% rename from lib/mpv/src/models/mpv_log_level.dart rename to lib/mpv/src/models/player_log_level.dart index 147e90a3..3f60d694 100644 --- a/lib/mpv/src/models/mpv_log_level.dart +++ b/lib/mpv/src/models/player_log_level.dart @@ -1,5 +1,5 @@ -/// Log level for MPV player messages. -enum MpvLogLevel { +/// Log level for player messages. +enum PlayerLogLevel { /// No logging. none, diff --git a/lib/mpv/src/models/mpv_subtitle_track.dart b/lib/mpv/src/models/subtitle_track.dart similarity index 82% rename from lib/mpv/src/models/mpv_subtitle_track.dart rename to lib/mpv/src/models/subtitle_track.dart index bcc98fad..0c75b2dc 100644 --- a/lib/mpv/src/models/mpv_subtitle_track.dart +++ b/lib/mpv/src/models/subtitle_track.dart @@ -1,5 +1,5 @@ /// Represents a subtitle track in the media. -class MpvSubtitleTrack { +class SubtitleTrack { /// Unique identifier for the track. final String id; @@ -24,7 +24,7 @@ class MpvSubtitleTrack { /// URI of external subtitle file (if isExternal is true). final String? uri; - const MpvSubtitleTrack({ + const SubtitleTrack({ required this.id, this.title, this.language, @@ -36,12 +36,12 @@ class MpvSubtitleTrack { }); /// Create a subtitle track from an external URI. - factory MpvSubtitleTrack.uri( + factory SubtitleTrack.uri( String uri, { String? title, String? language, }) { - return MpvSubtitleTrack( + return SubtitleTrack( id: 'external:$uri', title: title, language: language, @@ -51,10 +51,10 @@ class MpvSubtitleTrack { } /// Auto-select track. - static const auto = MpvSubtitleTrack(id: 'auto', title: 'Auto'); + static const auto = SubtitleTrack(id: 'auto', title: 'Auto'); /// Disable subtitles. - static const off = MpvSubtitleTrack(id: 'no', title: 'Off'); + static const off = SubtitleTrack(id: 'no', title: 'Off'); /// Returns a display name for the track. String get displayName { @@ -65,12 +65,12 @@ class MpvSubtitleTrack { } @override - String toString() => 'MpvSubtitleTrack($id, $displayName)'; + String toString() => 'SubtitleTrack($id, $displayName)'; @override bool operator ==(Object other) => identical(this, other) || - other is MpvSubtitleTrack && + other is SubtitleTrack && runtimeType == other.runtimeType && id == other.id; diff --git a/lib/mpv/src/models/track_selection.dart b/lib/mpv/src/models/track_selection.dart new file mode 100644 index 00000000..284b46e1 --- /dev/null +++ b/lib/mpv/src/models/track_selection.dart @@ -0,0 +1,30 @@ +import 'audio_track.dart'; +import 'subtitle_track.dart'; + +/// Represents the currently selected tracks. +class TrackSelection { + /// Currently selected audio track. + final AudioTrack? audio; + + /// Currently selected subtitle track. + final SubtitleTrack? subtitle; + + const TrackSelection({ + this.audio, + this.subtitle, + }); + + /// Creates a copy with the given fields replaced. + TrackSelection copyWith({ + AudioTrack? audio, + SubtitleTrack? subtitle, + }) { + return TrackSelection( + audio: audio ?? this.audio, + subtitle: subtitle ?? this.subtitle, + ); + } + + @override + String toString() => 'TrackSelection(audio: $audio, subtitle: $subtitle)'; +} diff --git a/lib/mpv/src/models/mpv_tracks.dart b/lib/mpv/src/models/tracks.dart similarity index 50% rename from lib/mpv/src/models/mpv_tracks.dart rename to lib/mpv/src/models/tracks.dart index 7b208b34..18fe3607 100644 --- a/lib/mpv/src/models/mpv_tracks.dart +++ b/lib/mpv/src/models/tracks.dart @@ -1,25 +1,25 @@ -import 'mpv_audio_track.dart'; -import 'mpv_subtitle_track.dart'; +import 'audio_track.dart'; +import 'subtitle_track.dart'; /// Container for all available tracks in the media. -class MpvTracks { +class Tracks { /// Available audio tracks. - final List audio; + final List audio; /// Available subtitle tracks. - final List subtitle; + final List subtitle; - const MpvTracks({ + const Tracks({ this.audio = const [], this.subtitle = const [], }); /// Creates a copy with the given fields replaced. - MpvTracks copyWith({ - List? audio, - List? subtitle, + Tracks copyWith({ + List? audio, + List? subtitle, }) { - return MpvTracks( + return Tracks( audio: audio ?? this.audio, subtitle: subtitle ?? this.subtitle, ); @@ -27,5 +27,5 @@ class MpvTracks { @override String toString() => - 'MpvTracks(audio: ${audio.length}, subtitle: ${subtitle.length})'; + 'Tracks(audio: ${audio.length}, subtitle: ${subtitle.length})'; } diff --git a/lib/mpv/src/player/mpv_player_android.dart b/lib/mpv/src/player/mpv_player_android.dart deleted file mode 100644 index 9490ab46..00000000 --- a/lib/mpv/src/player/mpv_player_android.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'mpv_player_native.dart'; - -/// Android implementation of MpvPlayer. -/// Inherits all functionality from MpvPlayerNative. -class MpvPlayerAndroid extends MpvPlayerNative {} diff --git a/lib/mpv/src/player/mpv_player_ios.dart b/lib/mpv/src/player/mpv_player_ios.dart deleted file mode 100644 index 6eba1c9b..00000000 --- a/lib/mpv/src/player/mpv_player_ios.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'mpv_player_native.dart'; - -/// iOS implementation of MpvPlayer. -/// Inherits all functionality from MpvPlayerNative. -class MpvPlayerIOS extends MpvPlayerNative {} diff --git a/lib/mpv/src/player/mpv_player_macos.dart b/lib/mpv/src/player/mpv_player_macos.dart deleted file mode 100644 index 76d7b1bc..00000000 --- a/lib/mpv/src/player/mpv_player_macos.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'mpv_player_native.dart'; - -/// macOS implementation of MpvPlayer. -/// Inherits all functionality from MpvPlayerNative. -class MpvPlayerMacOS extends MpvPlayerNative {} diff --git a/lib/mpv/src/player/mpv_player.dart b/lib/mpv/src/player/player.dart similarity index 77% rename from lib/mpv/src/player/mpv_player.dart rename to lib/mpv/src/player/player.dart index 2d518b71..7e4df9ca 100644 --- a/lib/mpv/src/player/mpv_player.dart +++ b/lib/mpv/src/player/player.dart @@ -1,27 +1,27 @@ import 'dart:io' show Platform; -import '../models/mpv_audio_device.dart'; -import '../models/mpv_media.dart'; -import '../models/mpv_audio_track.dart'; -import '../models/mpv_subtitle_track.dart'; -import 'mpv_player_android.dart'; -import 'mpv_player_ios.dart'; -import 'mpv_player_linux.dart'; -import 'mpv_player_macos.dart'; -import 'mpv_player_state.dart'; -import 'mpv_player_streams.dart'; -import 'mpv_player_stub.dart'; -import 'mpv_player_windows.dart'; +import '../models/audio_device.dart'; +import '../models/media.dart'; +import '../models/audio_track.dart'; +import '../models/subtitle_track.dart'; +import 'player_android.dart'; +import 'player_ios.dart'; +import 'player_linux.dart'; +import 'player_macos.dart'; +import 'player_state.dart'; +import 'player_streams.dart'; +import 'player_stub.dart'; +import 'player_windows.dart'; -/// Abstract interface for the MPV player. +/// Abstract interface for the video player. /// /// This interface defines all playback control methods, state access, /// and reactive streams for the video player. /// /// Example usage: /// ```dart -/// final player = MpvPlayer(); -/// await player.open(MpvMedia('https://example.com/video.mp4')); +/// final player = Player(); +/// await player.open(Media('https://example.com/video.mp4')); /// await player.play(); /// /// // Configure player properties @@ -36,16 +36,16 @@ import 'mpv_player_windows.dart'; /// // Access current state /// print('Playing: ${player.state.playing}'); /// ``` -abstract class MpvPlayer { +abstract class Player { /// Current synchronous state snapshot. /// /// Use this for immediate state access in UI. - MpvPlayerState get state; + PlayerState get state; /// Reactive streams for state changes. /// /// Use these for reactive UI updates. - MpvPlayerStreams get streams; + PlayerStreams get streams; /// Texture ID for Flutter's Texture widget (video rendering). /// @@ -61,7 +61,7 @@ abstract class MpvPlayer { /// /// [media] - The media source to open. /// [play] - Whether to start playback immediately (default: true). - Future open(MpvMedia media, {bool play = true}); + Future open(Media media, {bool play = true}); /// Start or resume playback. Future play(); @@ -83,12 +83,12 @@ abstract class MpvPlayer { // ============================================ /// Select an audio track. - Future selectAudioTrack(MpvAudioTrack track); + Future selectAudioTrack(AudioTrack track); /// Select a subtitle track. /// - /// Pass [MpvSubtitleTrack.off] to disable subtitles. - Future selectSubtitleTrack(MpvSubtitleTrack track); + /// Pass [SubtitleTrack.off] to disable subtitles. + Future selectSubtitleTrack(SubtitleTrack track); /// Add an external subtitle track. /// @@ -120,7 +120,7 @@ abstract class MpvPlayer { /// Set the audio output device. /// /// [device] - The audio device to use. - Future setAudioDevice(MpvAudioDevice device); + Future setAudioDevice(AudioDevice device); // ============================================ // MPV Properties (Advanced) @@ -194,31 +194,31 @@ abstract class MpvPlayer { // Factory // ============================================ - /// Creates a new MPV player instance. + /// Creates a new player instance. /// /// Returns a platform-specific implementation: - /// - macOS: [MpvPlayerMacOS] using MPVKit with Metal rendering - /// - iOS: [MpvPlayerIOS] using MPVKit with Metal rendering - /// - Android: [MpvPlayerAndroid] using libmpv - /// - Windows: [MpvPlayerWindows] using libmpv with native window embedding - /// - Linux: [MpvPlayerLinux] using libmpv with OpenGL rendering via GtkGLArea - /// - Other platforms: [MpvPlayerStub] (placeholder) - factory MpvPlayer() { + /// - macOS: [PlayerMacOS] using MPVKit with Metal rendering + /// - iOS: [PlayerIOS] using MPVKit with Metal rendering + /// - Android: [PlayerAndroid] using libmpv + /// - Windows: [PlayerWindows] using libmpv with native window embedding + /// - Linux: [PlayerLinux] using libmpv with OpenGL rendering via GtkGLArea + /// - Other platforms: [PlayerStub] (placeholder) + factory Player() { if (Platform.isMacOS) { - return MpvPlayerMacOS(); + return PlayerMacOS(); } if (Platform.isIOS) { - return MpvPlayerIOS(); + return PlayerIOS(); } if (Platform.isAndroid) { - return MpvPlayerAndroid(); + return PlayerAndroid(); } if (Platform.isWindows) { - return MpvPlayerWindows(); + return PlayerWindows(); } if (Platform.isLinux) { - return MpvPlayerLinux(); + return PlayerLinux(); } - return MpvPlayerStub(); + return PlayerStub(); } } diff --git a/lib/mpv/src/player/player_android.dart b/lib/mpv/src/player/player_android.dart new file mode 100644 index 00000000..6d8cb01b --- /dev/null +++ b/lib/mpv/src/player/player_android.dart @@ -0,0 +1,5 @@ +import 'player_native.dart'; + +/// Android implementation of Player. +/// Inherits all functionality from PlayerNative. +class PlayerAndroid extends PlayerNative {} diff --git a/lib/mpv/src/player/player_ios.dart b/lib/mpv/src/player/player_ios.dart new file mode 100644 index 00000000..f5128307 --- /dev/null +++ b/lib/mpv/src/player/player_ios.dart @@ -0,0 +1,5 @@ +import 'player_native.dart'; + +/// iOS implementation of Player. +/// Inherits all functionality from PlayerNative. +class PlayerIOS extends PlayerNative {} diff --git a/lib/mpv/src/player/mpv_player_linux.dart b/lib/mpv/src/player/player_linux.dart similarity index 92% rename from lib/mpv/src/player/mpv_player_linux.dart rename to lib/mpv/src/player/player_linux.dart index fa94a0cb..392ac2be 100644 --- a/lib/mpv/src/player/mpv_player_linux.dart +++ b/lib/mpv/src/player/player_linux.dart @@ -1,14 +1,14 @@ import 'package:flutter/services.dart'; -import 'mpv_player_native.dart'; +import 'player_native.dart'; -/// Linux implementation of [MpvPlayer]. +/// Linux implementation of [Player]. /// /// Uses libmpv with OpenGL rendering via GtkGLArea. /// The mpv video is rendered to a GtkGLArea positioned behind /// the Flutter view using a GtkOverlay, with transparent regions /// in the Flutter UI allowing the video to show through. -class MpvPlayerLinux extends MpvPlayerNative { +class PlayerLinux extends PlayerNative { static const _methodChannel = MethodChannel('com.plezy/mpv_player'); @override diff --git a/lib/mpv/src/player/player_macos.dart b/lib/mpv/src/player/player_macos.dart new file mode 100644 index 00000000..019730b4 --- /dev/null +++ b/lib/mpv/src/player/player_macos.dart @@ -0,0 +1,5 @@ +import 'player_native.dart'; + +/// macOS implementation of Player. +/// Inherits all functionality from PlayerNative. +class PlayerMacOS extends PlayerNative {} diff --git a/lib/mpv/src/player/mpv_player_native.dart b/lib/mpv/src/player/player_native.dart similarity index 87% rename from lib/mpv/src/player/mpv_player_native.dart rename to lib/mpv/src/player/player_native.dart index 1c459a40..3967f55e 100644 --- a/lib/mpv/src/player/mpv_player_native.dart +++ b/lib/mpv/src/player/player_native.dart @@ -2,32 +2,32 @@ import 'dart:async'; import 'package:flutter/services.dart'; -import '../models/mpv_audio_device.dart'; -import '../models/mpv_audio_track.dart'; -import '../models/mpv_log.dart'; -import '../models/mpv_media.dart'; -import '../models/mpv_subtitle_track.dart'; -import '../models/mpv_track_selection.dart'; -import '../models/mpv_tracks.dart'; -import 'mpv_player.dart'; -import 'mpv_player_state.dart'; -import 'mpv_player_streams.dart'; +import '../models/audio_device.dart'; +import '../models/audio_track.dart'; +import '../models/player_log.dart'; +import '../models/media.dart'; +import '../models/subtitle_track.dart'; +import '../models/track_selection.dart'; +import '../models/tracks.dart'; +import 'player.dart'; +import 'player_state.dart'; +import 'player_streams.dart'; -/// Shared native implementation of [MpvPlayer] for iOS and macOS. +/// Shared native implementation of [Player] for iOS and macOS. /// Uses MPVKit via platform channels with Metal rendering. -class MpvPlayerNative implements MpvPlayer { +class PlayerNative implements Player { static const _methodChannel = MethodChannel('com.plezy/mpv_player'); static const _eventChannel = EventChannel('com.plezy/mpv_player/events'); - MpvPlayerState _state = const MpvPlayerState(); + PlayerState _state = const PlayerState(); @override - MpvPlayerState get state => _state; + PlayerState get state => _state; - late final MpvPlayerStreams _streams; + late final PlayerStreams _streams; @override - MpvPlayerStreams get streams => _streams; + PlayerStreams get streams => _streams; @override int? get textureId => null; // Uses direct Metal layer, not Flutter texture @@ -41,21 +41,21 @@ class MpvPlayerNative implements MpvPlayer { final _bufferController = StreamController.broadcast(); final _volumeController = StreamController.broadcast(); final _rateController = StreamController.broadcast(); - final _tracksController = StreamController.broadcast(); - final _trackController = StreamController.broadcast(); - final _logController = StreamController.broadcast(); + final _tracksController = StreamController.broadcast(); + final _trackController = StreamController.broadcast(); + final _logController = StreamController.broadcast(); final _errorController = StreamController.broadcast(); - final _audioDeviceController = StreamController.broadcast(); + final _audioDeviceController = StreamController.broadcast(); final _audioDevicesController = - StreamController>.broadcast(); + StreamController>.broadcast(); StreamSubscription? _eventSubscription; bool _disposed = false; bool _initialized = false; bool _isVisible = false; - MpvPlayerNative() { - _streams = MpvPlayerStreams( + PlayerNative() { + _streams = PlayerStreams( playing: _playingController.stream, completed: _completedController.stream, buffering: _bufferingController.stream, @@ -195,9 +195,9 @@ class MpvPlayerNative implements MpvPlayer { } } - MpvTracks _parseTrackList(List trackList) { - final audioTracks = []; - final subtitleTracks = []; + Tracks _parseTrackList(List trackList) { + final audioTracks = []; + final subtitleTracks = []; for (final track in trackList) { if (track is! Map) continue; @@ -206,7 +206,7 @@ class MpvPlayerNative implements MpvPlayer { final id = track['id']?.toString() ?? ''; if (type == 'audio') { - audioTracks.add(MpvAudioTrack( + audioTracks.add(AudioTrack( id: id, title: track['title'] as String?, language: track['lang'] as String?, @@ -216,7 +216,7 @@ class MpvPlayerNative implements MpvPlayer { isDefault: track['default'] as bool? ?? false, )); } else if (type == 'sub') { - subtitleTracks.add(MpvSubtitleTrack( + subtitleTracks.add(SubtitleTrack( id: id, title: track['title'] as String?, language: track['lang'] as String?, @@ -227,15 +227,15 @@ class MpvPlayerNative implements MpvPlayer { } } - return MpvTracks(audio: audioTracks, subtitle: subtitleTracks); + return Tracks(audio: audioTracks, subtitle: subtitleTracks); } void _updateSelectedAudioTrack(dynamic trackId) { final id = trackId?.toString(); - MpvAudioTrack? selectedTrack; + AudioTrack? selectedTrack; if (id != null && id != 'no') { - selectedTrack = _state.tracks.audio.cast().firstWhere( + selectedTrack = _state.tracks.audio.cast().firstWhere( (t) => t?.id == id, orElse: () => null, ); @@ -249,11 +249,11 @@ class MpvPlayerNative implements MpvPlayer { void _updateSelectedSubtitleTrack(dynamic trackId) { final id = trackId?.toString(); - MpvSubtitleTrack? selectedTrack; + SubtitleTrack? selectedTrack; if (id != null && id != 'no') { selectedTrack = - _state.tracks.subtitle.cast().firstWhere( + _state.tracks.subtitle.cast().firstWhere( (t) => t?.id == id, orElse: () => null, ); @@ -272,7 +272,7 @@ class MpvPlayerNative implements MpvPlayer { final result = await _methodChannel.invokeMethod('initialize'); _initialized = result == true; if (!_initialized) { - throw Exception('Failed to initialize MPV player'); + throw Exception('Failed to initialize player'); } // Subscribe to MPV properties @@ -300,7 +300,7 @@ class MpvPlayerNative implements MpvPlayer { void _checkDisposed() { if (_disposed) { - throw StateError('MpvPlayer has been disposed'); + throw StateError('Player has been disposed'); } } @@ -309,7 +309,7 @@ class MpvPlayerNative implements MpvPlayer { // ============================================ @override - Future open(MpvMedia media, {bool play = true}) async { + Future open(Media media, {bool play = true}) async { _checkDisposed(); await _ensureInitialized(); @@ -376,13 +376,13 @@ class MpvPlayerNative implements MpvPlayer { // ============================================ @override - Future selectAudioTrack(MpvAudioTrack track) async { + Future selectAudioTrack(AudioTrack track) async { _checkDisposed(); await setProperty('aid', track.id); } @override - Future selectSubtitleTrack(MpvSubtitleTrack track) async { + Future selectSubtitleTrack(SubtitleTrack track) async { _checkDisposed(); await setProperty('sid', track.id); } @@ -418,7 +418,7 @@ class MpvPlayerNative implements MpvPlayer { } @override - Future setAudioDevice(MpvAudioDevice device) async { + Future setAudioDevice(AudioDevice device) async { _checkDisposed(); await setProperty('audio-device', device.name); } diff --git a/lib/mpv/src/player/mpv_player_state.dart b/lib/mpv/src/player/player_state.dart similarity index 76% rename from lib/mpv/src/player/mpv_player_state.dart rename to lib/mpv/src/player/player_state.dart index bad56556..475ee3f7 100644 --- a/lib/mpv/src/player/mpv_player_state.dart +++ b/lib/mpv/src/player/player_state.dart @@ -1,12 +1,12 @@ -import '../models/mpv_audio_device.dart'; -import '../models/mpv_tracks.dart'; -import '../models/mpv_track_selection.dart'; +import '../models/audio_device.dart'; +import '../models/tracks.dart'; +import '../models/track_selection.dart'; /// Immutable snapshot of the current player state. /// /// This class provides synchronous access to the player's current state. -/// For reactive updates, use [MpvPlayerStreams]. -class MpvPlayerState { +/// For reactive updates, use [PlayerStreams]. +class PlayerState { /// Whether playback is currently active. final bool playing; @@ -32,10 +32,10 @@ class MpvPlayerState { final double rate; /// Available tracks in the media. - final MpvTracks tracks; + final Tracks tracks; /// Currently selected tracks. - final MpvTrackSelection track; + final TrackSelection track; /// Audio delay/sync offset in seconds. final double audioDelay; @@ -47,12 +47,12 @@ class MpvPlayerState { final bool audioPassthrough; /// Current audio output device. - final MpvAudioDevice audioDevice; + final AudioDevice audioDevice; /// Available audio output devices. - final List audioDevices; + final List audioDevices; - const MpvPlayerState({ + const PlayerState({ this.playing = false, this.completed = false, this.buffering = false, @@ -61,17 +61,17 @@ class MpvPlayerState { this.buffer = Duration.zero, this.volume = 100.0, this.rate = 1.0, - this.tracks = const MpvTracks(), - this.track = const MpvTrackSelection(), + this.tracks = const Tracks(), + this.track = const TrackSelection(), this.audioDelay = 0.0, this.subtitleDelay = 0.0, this.audioPassthrough = false, - this.audioDevice = MpvAudioDevice.auto, + this.audioDevice = AudioDevice.auto, this.audioDevices = const [], }); /// Creates a copy with the given fields replaced. - MpvPlayerState copyWith({ + PlayerState copyWith({ bool? playing, bool? completed, bool? buffering, @@ -80,15 +80,15 @@ class MpvPlayerState { Duration? buffer, double? volume, double? rate, - MpvTracks? tracks, - MpvTrackSelection? track, + Tracks? tracks, + TrackSelection? track, double? audioDelay, double? subtitleDelay, bool? audioPassthrough, - MpvAudioDevice? audioDevice, - List? audioDevices, + AudioDevice? audioDevice, + List? audioDevices, }) { - return MpvPlayerState( + return PlayerState( playing: playing ?? this.playing, completed: completed ?? this.completed, buffering: buffering ?? this.buffering, @@ -109,5 +109,5 @@ class MpvPlayerState { @override String toString() => - 'MpvPlayerState(playing: $playing, position: $position, duration: $duration)'; + 'PlayerState(playing: $playing, position: $position, duration: $duration)'; } diff --git a/lib/mpv/src/player/mpv_player_streams.dart b/lib/mpv/src/player/player_streams.dart similarity index 72% rename from lib/mpv/src/player/mpv_player_streams.dart rename to lib/mpv/src/player/player_streams.dart index 7a240f36..cda0ba9e 100644 --- a/lib/mpv/src/player/mpv_player_streams.dart +++ b/lib/mpv/src/player/player_streams.dart @@ -1,13 +1,13 @@ -import '../models/mpv_audio_device.dart'; -import '../models/mpv_log.dart'; -import '../models/mpv_tracks.dart'; -import '../models/mpv_track_selection.dart'; +import '../models/audio_device.dart'; +import '../models/player_log.dart'; +import '../models/tracks.dart'; +import '../models/track_selection.dart'; /// Reactive streams for player state changes. /// /// Subscribe to these streams to receive updates when the player state changes. -/// For synchronous state access, use [MpvPlayerState]. -class MpvPlayerStreams { +/// For synchronous state access, use [PlayerState]. +class PlayerStreams { /// Stream of playing state changes. final Stream playing; @@ -33,24 +33,24 @@ class MpvPlayerStreams { final Stream rate; /// Stream of available tracks updates. - final Stream tracks; + final Stream tracks; /// Stream of track selection changes. - final Stream track; + final Stream track; - /// Stream of log messages from MPV. - final Stream log; + /// Stream of log messages from the player. + final Stream log; /// Stream of error messages. final Stream error; /// Stream of audio device changes. - final Stream audioDevice; + final Stream audioDevice; /// Stream of available audio devices. - final Stream> audioDevices; + final Stream> audioDevices; - const MpvPlayerStreams({ + const PlayerStreams({ required this.playing, required this.completed, required this.buffering, diff --git a/lib/mpv/src/player/mpv_player_stub.dart b/lib/mpv/src/player/player_stub.dart similarity index 67% rename from lib/mpv/src/player/mpv_player_stub.dart rename to lib/mpv/src/player/player_stub.dart index f4bce796..72dd6286 100644 --- a/lib/mpv/src/player/mpv_player_stub.dart +++ b/lib/mpv/src/player/player_stub.dart @@ -1,31 +1,31 @@ import 'dart:async'; -import '../models/mpv_audio_device.dart'; -import '../models/mpv_media.dart'; -import '../models/mpv_audio_track.dart'; -import '../models/mpv_subtitle_track.dart'; -import '../models/mpv_tracks.dart'; -import '../models/mpv_track_selection.dart'; -import '../models/mpv_log.dart'; -import 'mpv_player.dart'; -import 'mpv_player_state.dart'; -import 'mpv_player_streams.dart'; +import '../models/audio_device.dart'; +import '../models/media.dart'; +import '../models/audio_track.dart'; +import '../models/subtitle_track.dart'; +import '../models/tracks.dart'; +import '../models/track_selection.dart'; +import '../models/player_log.dart'; +import 'player.dart'; +import 'player_state.dart'; +import 'player_streams.dart'; -/// Stub implementation of [MpvPlayer]. +/// Stub implementation of [Player]. /// /// This implementation creates all the necessary stream controllers and /// state management, but throws [UnimplementedError] for all playback /// methods. It serves as a foundation for platform-specific implementations. -class MpvPlayerStub implements MpvPlayer { - MpvPlayerState _state = const MpvPlayerState(); +class PlayerStub implements Player { + PlayerState _state = const PlayerState(); @override - MpvPlayerState get state => _state; + PlayerState get state => _state; - late final MpvPlayerStreams _streams; + late final PlayerStreams _streams; @override - MpvPlayerStreams get streams => _streams; + PlayerStreams get streams => _streams; @override int? get textureId => null; // Set by platform implementation @@ -39,18 +39,18 @@ class MpvPlayerStub implements MpvPlayer { final _bufferController = StreamController.broadcast(); final _volumeController = StreamController.broadcast(); final _rateController = StreamController.broadcast(); - final _tracksController = StreamController.broadcast(); - final _trackController = StreamController.broadcast(); - final _logController = StreamController.broadcast(); + final _tracksController = StreamController.broadcast(); + final _trackController = StreamController.broadcast(); + final _logController = StreamController.broadcast(); final _errorController = StreamController.broadcast(); - final _audioDeviceController = StreamController.broadcast(); + final _audioDeviceController = StreamController.broadcast(); final _audioDevicesController = - StreamController>.broadcast(); + StreamController>.broadcast(); bool _disposed = false; - MpvPlayerStub() { - _streams = MpvPlayerStreams( + PlayerStub() { + _streams = PlayerStreams( playing: _playingController.stream, completed: _completedController.stream, buffering: _bufferingController.stream, @@ -70,7 +70,7 @@ class MpvPlayerStub implements MpvPlayer { void _checkDisposed() { if (_disposed) { - throw StateError('MpvPlayer has been disposed'); + throw StateError('Player has been disposed'); } } @@ -79,21 +79,21 @@ class MpvPlayerStub implements MpvPlayer { // ============================================ @override - Future open(MpvMedia media, {bool play = true}) async { + Future open(Media media, {bool play = true}) async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.open() is not yet implemented'); + throw UnimplementedError('Player.open() is not yet implemented'); } @override Future play() async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.play() is not yet implemented'); + throw UnimplementedError('Player.play() is not yet implemented'); } @override Future pause() async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.pause() is not yet implemented'); + throw UnimplementedError('Player.pause() is not yet implemented'); } @override @@ -109,13 +109,13 @@ class MpvPlayerStub implements MpvPlayer { @override Future stop() async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.stop() is not yet implemented'); + throw UnimplementedError('Player.stop() is not yet implemented'); } @override Future seek(Duration position) async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.seek() is not yet implemented'); + throw UnimplementedError('Player.seek() is not yet implemented'); } // ============================================ @@ -123,17 +123,17 @@ class MpvPlayerStub implements MpvPlayer { // ============================================ @override - Future selectAudioTrack(MpvAudioTrack track) async { + Future selectAudioTrack(AudioTrack track) async { _checkDisposed(); throw UnimplementedError( - 'MpvPlayer.selectAudioTrack() is not yet implemented'); + 'Player.selectAudioTrack() is not yet implemented'); } @override - Future selectSubtitleTrack(MpvSubtitleTrack track) async { + Future selectSubtitleTrack(SubtitleTrack track) async { _checkDisposed(); throw UnimplementedError( - 'MpvPlayer.selectSubtitleTrack() is not yet implemented'); + 'Player.selectSubtitleTrack() is not yet implemented'); } @override @@ -145,7 +145,7 @@ class MpvPlayerStub implements MpvPlayer { }) async { _checkDisposed(); throw UnimplementedError( - 'MpvPlayer.addSubtitleTrack() is not yet implemented'); + 'Player.addSubtitleTrack() is not yet implemented'); } // ============================================ @@ -155,20 +155,20 @@ class MpvPlayerStub implements MpvPlayer { @override Future setVolume(double volume) async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.setVolume() is not yet implemented'); + throw UnimplementedError('Player.setVolume() is not yet implemented'); } @override Future setRate(double rate) async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.setRate() is not yet implemented'); + throw UnimplementedError('Player.setRate() is not yet implemented'); } @override - Future setAudioDevice(MpvAudioDevice device) async { + Future setAudioDevice(AudioDevice device) async { _checkDisposed(); throw UnimplementedError( - 'MpvPlayer.setAudioDevice() is not yet implemented'); + 'Player.setAudioDevice() is not yet implemented'); } // ============================================ @@ -178,19 +178,19 @@ class MpvPlayerStub implements MpvPlayer { @override Future setProperty(String name, String value) async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.setProperty() is not yet implemented'); + throw UnimplementedError('Player.setProperty() is not yet implemented'); } @override Future getProperty(String name) async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.getProperty() is not yet implemented'); + throw UnimplementedError('Player.getProperty() is not yet implemented'); } @override Future command(List args) async { _checkDisposed(); - throw UnimplementedError('MpvPlayer.command() is not yet implemented'); + throw UnimplementedError('Player.command() is not yet implemented'); } // ============================================ @@ -201,7 +201,7 @@ class MpvPlayerStub implements MpvPlayer { Future setAudioPassthrough(bool enabled) async { _checkDisposed(); throw UnimplementedError( - 'MpvPlayer.setAudioPassthrough() is not yet implemented'); + 'Player.setAudioPassthrough() is not yet implemented'); } // ============================================ diff --git a/lib/mpv/src/player/mpv_player_windows.dart b/lib/mpv/src/player/player_windows.dart similarity index 81% rename from lib/mpv/src/player/mpv_player_windows.dart rename to lib/mpv/src/player/player_windows.dart index 278838f7..569f8dff 100644 --- a/lib/mpv/src/player/mpv_player_windows.dart +++ b/lib/mpv/src/player/player_windows.dart @@ -1,13 +1,13 @@ import 'package:flutter/services.dart'; -import 'mpv_player_native.dart'; +import 'player_native.dart'; -/// Windows implementation of [MpvPlayer]. +/// Windows implementation of [Player]. /// /// Uses libmpv via platform channels with native window embedding. /// The mpv video window is positioned behind the Flutter window, /// with transparent regions allowing the video to show through. -class MpvPlayerWindows extends MpvPlayerNative { +class PlayerWindows extends PlayerNative { static const _methodChannel = MethodChannel('com.plezy/mpv_player'); @override @@ -15,7 +15,7 @@ class MpvPlayerWindows extends MpvPlayerNative { /// Updates the video window position and size. /// - /// This is called by [MpvVideo] when the widget layout changes. + /// This is called by [Video] when the widget layout changes. Future setVideoRect({ required int left, required int top, diff --git a/lib/mpv/src/video/mpv_video.dart b/lib/mpv/src/video/video.dart similarity index 85% rename from lib/mpv/src/video/mpv_video.dart rename to lib/mpv/src/video/video.dart index 80233ff1..e5de5071 100644 --- a/lib/mpv/src/video/mpv_video.dart +++ b/lib/mpv/src/video/video.dart @@ -2,28 +2,28 @@ import 'dart:io' show Platform; import 'package:flutter/material.dart'; -import '../player/mpv_player.dart'; -import '../player/mpv_player_linux.dart'; -import '../player/mpv_player_windows.dart'; +import '../player/player.dart'; +import '../player/player_linux.dart'; +import '../player/player_windows.dart'; -/// Video widget for displaying MPV player output. +/// Video widget for displaying player output. /// -/// This widget displays the video output from an [MpvPlayer] instance +/// This widget displays the video output from a [Player] instance /// and optionally overlays custom controls. /// /// Example usage: /// ```dart -/// final player = MpvPlayer(); +/// final player = Player(); /// -/// MpvVideo( +/// Video( /// player: player, /// fit: BoxFit.contain, /// controls: (context) => MyCustomControls(), /// ) /// ``` -class MpvVideo extends StatefulWidget { +class Video extends StatefulWidget { /// The player instance. - final MpvPlayer player; + final Player player; /// How the video should be inscribed into the widget's box. final BoxFit fit; @@ -34,7 +34,7 @@ class MpvVideo extends StatefulWidget { /// Background color shown behind the video. final Color backgroundColor; - const MpvVideo({ + const Video({ super.key, required this.player, this.fit = BoxFit.contain, @@ -43,10 +43,10 @@ class MpvVideo extends StatefulWidget { }); @override - State createState() => _MpvVideoState(); + State