Skip to content

Commit

Permalink
Merge branch 'master' into fix/audio_playback_when_using_proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
lamarios authored Dec 6, 2023
2 parents b38cce2 + c5ec466 commit 3da3144
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 23 deletions.
85 changes: 66 additions & 19 deletions lib/player/states/player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import 'package:invidious/globals.dart';
import 'package:invidious/player/models/mediaCommand.dart';
import 'package:invidious/player/models/mediaEvent.dart';
import 'package:invidious/player/states/interfaces/media_player.dart';
import 'package:invidious/utils.dart';
import 'package:invidious/utils/models/image_object.dart';
import 'package:logging/logging.dart';
import 'package:native_device_orientation/native_device_orientation.dart';
import 'package:simple_pip_mode/simple_pip.dart';

import '../../downloads/models/downloaded_video.dart';
Expand Down Expand Up @@ -43,6 +45,7 @@ enum PlayerRepeat { noRepeat, repeatAll, repeatOne }

class PlayerCubit extends Cubit<PlayerState> {
final SettingsCubit settings;
late final StreamSubscription<NativeDeviceOrientation> deviceOrientationStream;

PlayerCubit(super.initialState, this.settings) {
onReady();
Expand All @@ -66,7 +69,13 @@ class PlayerCubit extends Cubit<PlayerState> {
MediaControl.stop,
state.hasQueue ? MediaControl.skipToNext : MediaControl.fastForward,
],
systemActions: const {MediaAction.seek, MediaAction.seekForward, MediaAction.seekBackward, MediaAction.setShuffleMode, MediaAction.setRepeatMode},
systemActions: const {
MediaAction.seek,
MediaAction.seekForward,
MediaAction.seekBackward,
MediaAction.setShuffleMode,
MediaAction.setRepeatMode
},
androidCompactActionIndices: const [0, 1, 3],
processingState: const {
MediaState.idle: AudioProcessingState.idle,
Expand All @@ -90,11 +99,15 @@ class PlayerCubit extends Cubit<PlayerState> {

int get currentIndex {
String? currentVideoId = state.currentlyPlaying?.videoId ?? state.offlineCurrentlyPlaying?.videoId;
return (state.videos.isNotEmpty ? state.videos : state.offlineVideos).indexWhere((element) => element.videoId == currentVideoId);
return (state.videos.isNotEmpty ? state.videos : state.offlineVideos)
.indexWhere((element) => element.videoId == currentVideoId);
}

onReady() async {
if (!isTv) {
deviceOrientationStream =
NativeDeviceOrientationCommunicator().onOrientationChanged(useSensor: true).listen(this.onOrientationChange);

mediaHandler = await AudioService.init(
builder: () => MediaHandler(this),
config: const AudioServiceConfig(
Expand Down Expand Up @@ -163,6 +176,7 @@ class PlayerCubit extends Cubit<PlayerState> {
@override
close() async {
BackButtonInterceptor.removeByName('miniPlayer');
await deviceOrientationStream.cancel();
super.close();
}

Expand Down Expand Up @@ -203,7 +217,8 @@ class PlayerCubit extends Cubit<PlayerState> {
hide() {
var state = this.state.copyWith();
state.isMini = true;
state.mediaEvent = MediaEvent(state: MediaState.playing, type: MediaEventType.miniDisplayChanged, value: state.isMini);
state.mediaEvent =
MediaEvent(state: MediaState.playing, type: MediaEventType.miniDisplayChanged, value: state.isMini);
state.top = null;
state.height = targetHeight;
state.isHidden = true;
Expand Down Expand Up @@ -252,7 +267,9 @@ class PlayerCubit extends Cubit<PlayerState> {
state.offlineVideos = [];
if (videos.isNotEmpty) {
//removing videos that are already in the queue
state.videos.addAll(videos.where((v) => state.videos.indexWhere((v2) => v2.videoId == v.videoId) == -1).where((element) => !element.filtered));
state.videos.addAll(videos
.where((v) => state.videos.indexWhere((v2) => v2.videoId == v.videoId) == -1)
.where((element) => !element.filtered));
} else {
playVideo(videos);
}
Expand All @@ -264,18 +281,21 @@ class PlayerCubit extends Cubit<PlayerState> {
showBigPlayer() {
var state = this.state.copyWith();
state.isMini = false;
state.mediaEvent = MediaEvent(state: MediaState.playing, type: MediaEventType.miniDisplayChanged, value: state.isMini);
state.mediaEvent =
MediaEvent(state: MediaState.playing, type: MediaEventType.miniDisplayChanged, value: state.isMini);
state.top = 0;
state.opacity = 1;
state.isHidden = false;
emit(state);
NativeDeviceOrientationCommunicator().orientation(useSensor: true).then(onOrientationChange);
}

showMiniPlayer() {
if (state.currentlyPlaying != null || state.offlineCurrentlyPlaying != null) {
var state = this.state.copyWith();
state.isMini = true;
state.mediaEvent = MediaEvent(state: MediaState.playing, type: MediaEventType.miniDisplayChanged, value: state.isMini);
state.mediaEvent =
MediaEvent(state: MediaState.playing, type: MediaEventType.miniDisplayChanged, value: state.isMini);
state.top = null;
state.isHidden = false;
state.opacity = 1;
Expand All @@ -294,7 +314,8 @@ class PlayerCubit extends Cubit<PlayerState> {

if (state.sponsorSegments.isNotEmpty) {
double positionInMs = currentPosition * 1000;
Pair<int> nextSegment = state.sponsorSegments.firstWhere((e) => e.first <= positionInMs && positionInMs <= e.last, orElse: () => Pair<int>(-1, -1));
Pair<int> nextSegment = state.sponsorSegments
.firstWhere((e) => e.first <= positionInMs && positionInMs <= e.last, orElse: () => Pair<int>(-1, -1));
if (nextSegment.first != -1) {
emit(state.copyWith(mediaEvent: MediaEvent(state: MediaState.playing, type: MediaEventType.sponsorSkipped)));
//for some reasons this needs to be last
Expand Down Expand Up @@ -453,7 +474,6 @@ class PlayerCubit extends Cubit<PlayerState> {
setAudio(video.audioOnly);
}


state.mediaEvent = MediaEvent(state: MediaState.loading);

if (isOffline) {
Expand All @@ -477,7 +497,8 @@ class PlayerCubit extends Cubit<PlayerState> {
v = await service.getVideo(video.videoId);
}
state.currentlyPlaying = v;
state.mediaCommand = MediaCommand(MediaCommandType.switchVideo, value: SwitchVideoValue(video: v, startAt: startAt));
state.mediaCommand =
MediaCommand(MediaCommandType.switchVideo, value: SwitchVideoValue(video: v, startAt: startAt));
} else {
state.offlineCurrentlyPlaying = video;
state.mediaCommand = MediaCommand(MediaCommandType.switchToOfflineVideo, value: video);
Expand All @@ -496,11 +517,11 @@ class PlayerCubit extends Cubit<PlayerState> {
}
} catch (err) {
emit(state);
if(state.videos.length == 1) {
if (state.videos.length == 1) {
// if we can't get video details, we need to stop everything
log.severe("Couldn't play video '${video.videoId}', stopping player to avoid app crash");
hide();
}else{
} else {
// if we have more than 1 video
log.severe("Couldn't play video '${video.videoId}', removing it from the queue");

Expand Down Expand Up @@ -570,7 +591,8 @@ class PlayerCubit extends Cubit<PlayerState> {
// we change the display mode if there's a big enough drag movement to avoid jittery behavior when dragging slow
if (details.delta.dy.abs() > 3) {
state.isMini = details.delta.dy > 0;
state.mediaEvent = MediaEvent(state: MediaState.playing, type: MediaEventType.miniDisplayChanged, value: state.isMini);
state.mediaEvent =
MediaEvent(state: MediaState.playing, type: MediaEventType.miniDisplayChanged, value: state.isMini);
}
state.dragDistance += details.delta.dy;
// we're going down, putting threshold high easier to switch to mini player
Expand Down Expand Up @@ -633,7 +655,8 @@ class PlayerCubit extends Cubit<PlayerState> {
setSponsorBlock() async {
List<Pair<int>> newSegments = [];
if (state.currentlyPlaying != null) {
List<SponsorSegmentType> types = SponsorSegmentType.values.where((e) => db.getSettings(e.settingsName())?.value == 'true').toList();
List<SponsorSegmentType> types =
SponsorSegmentType.values.where((e) => db.getSettings(e.settingsName())?.value == 'true').toList();

if (types.isNotEmpty) {
List<SponsorSegment> sponsorSegments = await service.getSponsorSegments(state.currentlyPlaying!.videoId, types);
Expand All @@ -656,7 +679,8 @@ class PlayerCubit extends Cubit<PlayerState> {
duration = Duration.zero;
}

var videoLength = this.state.currentlyPlaying?.lengthSeconds ?? this.state.offlineCurrentlyPlaying?.lengthSeconds ?? 1;
var videoLength =
this.state.currentlyPlaying?.lengthSeconds ?? this.state.offlineCurrentlyPlaying?.lengthSeconds ?? 1;
if (duration.inSeconds > (videoLength)) {
duration = Duration(seconds: videoLength);
}
Expand Down Expand Up @@ -701,11 +725,22 @@ class PlayerCubit extends Cubit<PlayerState> {
if (state.videos.isNotEmpty) {
var e = state.videos[index];
return MediaItem(
id: e.videoId, title: e.title, artist: e.author, duration: Duration(seconds: e.lengthSeconds), album: '', artUri: Uri.parse(ImageObject.getBestThumbnail(e.videoThumbnails)?.url ?? ''));
id: e.videoId,
title: e.title,
artist: e.author,
duration: Duration(seconds: e.lengthSeconds),
album: '',
artUri: Uri.parse(ImageObject.getBestThumbnail(e.videoThumbnails)?.url ?? ''));
} else if (state.offlineVideos.isNotEmpty) {
var e = state.offlineVideos[index];
var path = await e.thumbnailPath;
return MediaItem(id: e.videoId, title: e.title, artist: e.author, duration: Duration(seconds: e.lengthSeconds), album: '', artUri: Uri.file(path));
return MediaItem(
id: e.videoId,
title: e.title,
artist: e.author,
duration: Duration(seconds: e.lengthSeconds),
album: '',
artUri: Uri.file(path));
}
return null;
}
Expand All @@ -720,7 +755,9 @@ class PlayerCubit extends Cubit<PlayerState> {
// emit(state.copyWith(mediaCommand: MediaCommand(MediaCommandType.fullScreen, value: fsState)));
emit(state.copyWith(
fullScreenState: fsState,
mediaCommand: MediaCommand(fsState == FullScreenState.notFullScreen ? MediaCommandType.exitFullScreen : MediaCommandType.enterFullScreen),
mediaCommand: MediaCommand(fsState == FullScreenState.notFullScreen
? MediaCommandType.exitFullScreen
: MediaCommandType.enterFullScreen),
mediaEvent: MediaEvent(state: state.mediaEvent.state, type: MediaEventType.fullScreenChanged, value: fsState)));

switch (fsState) {
Expand Down Expand Up @@ -763,7 +800,8 @@ class PlayerCubit extends Cubit<PlayerState> {
}
}

Duration get duration => Duration(seconds: (state.currentlyPlaying?.lengthSeconds ?? state.offlineCurrentlyPlaying?.lengthSeconds ?? 1));
Duration get duration =>
Duration(seconds: (state.currentlyPlaying?.lengthSeconds ?? state.offlineCurrentlyPlaying?.lengthSeconds ?? 1));

double get progress => state.position.inMilliseconds / duration.inMilliseconds;

Expand All @@ -778,7 +816,8 @@ class PlayerCubit extends Cubit<PlayerState> {
// get videos minus the one we already played and the currently playing video
List<String> videos = (state.videos.isNotEmpty ? state.videos : state.offlineVideos)
.where((element) => !state.playedVideos.contains(element.videoId))
.where((element) => element.videoId != (state.currentlyPlaying?.videoId ?? state.offlineCurrentlyPlaying?.videoId))
.where(
(element) => element.videoId != (state.currentlyPlaying?.videoId ?? state.offlineCurrentlyPlaying?.videoId))
.map((e) => e.videoId)
.toList();

Expand All @@ -790,6 +829,14 @@ class PlayerCubit extends Cubit<PlayerState> {
ListQueue<String> playQueue = ListQueue.from(videos);
emit(state.copyWith(playQueue: playQueue));
}

void onOrientationChange(NativeDeviceOrientation event) {
if (getDeviceType() == DeviceType.phone &&
(event == NativeDeviceOrientation.landscapeLeft || event == NativeDeviceOrientation.landscapeRight) &&
!state.isMini) {
setFullScreen(FullScreenState.fullScreen);
}
}
}

@CopyWith(constructor: "_")
Expand Down
10 changes: 6 additions & 4 deletions lib/search/states/search.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ class SearchCubit<T extends SearchState> extends Cubit<SearchState> {

void getSuggestions({bool hideResult = true}) {
emit(state.copyWith(showResults: !hideResult));
EasyDebounce.debounce('search-suggestions', const Duration(milliseconds: 500), () async {
var suggestions = (await service.getSearchSuggestion(state.queryController.value.text)).suggestions;
emit(state.copyWith(suggestions: suggestions));
});
if(!settings.state.distractionFreeMode) {
EasyDebounce.debounce('search-suggestions', const Duration(milliseconds: 500), () async {
var suggestions = (await service.getSearchSuggestion(state.queryController.value.text)).suggestions;
emit(state.copyWith(suggestions: suggestions));
});
}
}

List<String> getHistory() {
Expand Down
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
native_device_orientation:
dependency: "direct main"
description:
name: native_device_orientation
sha256: "744a03030fad5a332a54833cd34f1e2ee51ae9acf477b4ef85bacc8823af9937"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
nested:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ dependencies:
auto_route: 7.8.4
workmanager: 0.5.2
flutter_displaymode: 0.6.0
native_device_orientation: 1.2.1
dependency_overrides:
# wakelock_windows:
# git: # see https://github.com/creativecreatorormaybenot/wakelock/pull/203 for updates
Expand Down

0 comments on commit 3da3144

Please sign in to comment.