Skip to content

Commit

Permalink
initial ingration with audioplayers flutter plugin
Browse files Browse the repository at this point in the history
seek doesn't work on Endeavour OS (Arch)
  • Loading branch information
KRTirtho committed Jul 1, 2022
1 parent 4321668 commit f896f65
Show file tree
Hide file tree
Showing 17 changed files with 202 additions and 166 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/feature-audioplayers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: audioplayers integration build
on:
push:
branches:
- build
workflow_dispatch:

jobs:
build_ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: subosito/[email protected]
with:
cache: true
- run: |
sudo apt-get update -y
sudo apt-get install -y tar clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools patchelf desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
- run: flutter config --enable-linux-desktop
- run: flutter pub get
- run: dart bin/create-secrets.dart '${{ secrets.LYRICS_SECRET }}' '${{ secrets.SPOTIFY_SECRET }}'
- run: flutter clean
- run: flutter build linux
- run: make tar
- uses: actions/upload-artifact@v2
with:
name: Spotube-Linux-Bundle
path: build/Spotube-linux-x86_64.tar.xz
19 changes: 13 additions & 6 deletions CONTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ All types of contributions are encouraged and valued. See the [Table of Contents
## Table of Contents

- [Code of Conduct](#code-of-conduct)
- [I Have a Question](#i-have-a-question)
- [I Want To Contribute](#i-want-to-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Your First Code Contribution](#your-first-code-contribution)
- [Contributing to Spotube](#contributing-to-spotube)
- [Table of Contents](#table-of-contents)
- [Code of Conduct](#code-of-conduct)
- [I Have a Question](#i-have-a-question)
- [I Want To Contribute](#i-want-to-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Before Submitting a Bug Report](#before-submitting-a-bug-report)
- [How Do I Submit a Good Bug Report?](#how-do-i-submit-a-good-bug-report)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Your First Code Contribution](#your-first-code-contribution)


## Code of Conduct
Expand Down Expand Up @@ -109,6 +113,9 @@ Enhancement suggestions are tracked as [GitHub issues](https://github.com/KRTirt

### Your First Code Contribution

<!-- Download -->
audioplayers requirement https://github.com/bluefireteam/audioplayers/blob/main/packages/audioplayers_linux/requirements.md

Do the following:
- Download the latest Flutter SDK (>=2.15.1) & enable desktop support
- Install Development dependencies in linux
Expand Down
19 changes: 1 addition & 18 deletions lib/components/Player/Player.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
Expand Down Expand Up @@ -34,24 +35,6 @@ class Player extends HookConsumerWidget {
final AsyncSnapshot<SharedPreferences?> localStorage =
useFuture(future, initialData: null);

useEffect(() {
/// warm up the audio player before playing actual audio
/// It's for resolving unresolved issue related to just_audio's
/// [disposeAllPlayers] method which is throwing
/// [UnimplementedException] in the [PlatformInterface]
/// implementation
player.core.setAsset("assets/warmer.mp3");
return null;
}, []);

useEffect(() {
if (localStorage.hasData) {
_volume.value = localStorage.data?.getDouble(LocalStorageKeys.volume) ??
player.core.volume;
}
return null;
}, [localStorage.data]);

String albumArt = useMemoized(
() => imageToUrlString(
playback.currentTrack?.album?.images,
Expand Down
40 changes: 29 additions & 11 deletions lib/components/Player/PlayerControls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class PlayerControls extends HookConsumerWidget {
child: Column(
children: [
StreamBuilder<Duration>(
stream: player.core.positionStream,
stream: player.core.onPositionChanged,
builder: (context, snapshot) {
final totalMinutes =
zeroPadNumStr(duration.inMinutes.remainder(60));
Expand All @@ -48,23 +48,41 @@ class PlayerControls extends HookConsumerWidget {

final sliderMax = duration.inSeconds;
final sliderValue = snapshot.data?.inSeconds ?? 0;
// final value = (sliderMax == 0 || sliderValue > sliderMax)
// ? 0
// : sliderValue / sliderMax;

final _duration = playback.duration;
final _position = snapshot.data;
final value = (_position != null &&
_duration != null &&
_position.inMilliseconds > 0 &&
_position.inMilliseconds < _duration.inMilliseconds)
? _position.inMilliseconds / _duration.inMilliseconds
: 0.0;
return Column(
children: [
Slider.adaptive(
// cannot divide by zero
// there's an edge case for value being bigger
// than total duration. Keeping it resolved
value: (sliderMax == 0 || sliderValue > sliderMax)
? 0
: sliderValue / sliderMax,
onChanged: (value) {},
onChangeEnd: (value) {
player.seek(
Duration(
seconds: (value * sliderMax).toInt(),
),
);
value: value,
onChanged: (v) async {
final duration = _duration;
if (duration == null) {
return;
}
final position = v * duration.inMilliseconds;
await player
.seek(Duration(milliseconds: position.round()));
},
// onChangeEnd: (value) async {
// await player.seek(
// Duration(
// seconds: (value * sliderMax).toInt(),
// ),
// );
// },
activeColor: iconColor,
),
Padding(
Expand Down
6 changes: 2 additions & 4 deletions lib/helpers/search-youtube.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,8 @@ Future<SpotubeTrack> toSpotubeTrack({
"[YouTube Matched Track] ${ytVideo.title} | ${ytVideo.author} - ${ytVideo.url}",
);

final audioManifest = (Platform.isMacOS || Platform.isIOS)
? trackManifest.audioOnly
.where((info) => info.codec.mimeType == "audio/mp4")
: trackManifest.audioOnly;
final audioManifest = trackManifest.audioOnly
.where((info) => info.codec.mimeType == "audio/mp4");

final ytUri = (audioQuality == AudioQuality.high
? audioManifest.withHighestBitrate()
Expand Down
2 changes: 1 addition & 1 deletion lib/hooks/useSyncedLyrics.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ useSyncedLyrics(WidgetRef ref, Map<int, String> lyricsMap) {
final player = ref.watch(playbackProvider.select(
(value) => (value.player),
));
final stream = player.core.positionStream;
final stream = player.core.onPositionChanged;

final currentTime = useState(0);

Expand Down
18 changes: 9 additions & 9 deletions lib/interfaces/media_player2_player.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// This file was generated using the following command and may be overwritten.
// dart-dbus generate-object defs/org.mpris.MediaPlayer2.Player.xml

import 'package:audioplayers/audioplayers.dart';
import 'package:dbus/dbus.dart';
import 'package:just_audio/just_audio.dart';
import 'package:spotube/helpers/image-to-url-string.dart';
import 'package:spotube/models/SpotubeTrack.dart';
import 'package:spotube/provider/Playback.dart';
Expand All @@ -19,7 +19,7 @@ class Player_Interface extends DBusObject {

/// Gets value of property org.mpris.MediaPlayer2.Player.PlaybackStatus
Future<DBusMethodResponse> getPlaybackStatus() async {
final status = player.playing
final status = player.state == PlayerState.playing
? "Playing"
: playback.currentPlaylist == null
? "Stopped"
Expand All @@ -40,12 +40,12 @@ class Player_Interface extends DBusObject {

/// Gets value of property org.mpris.MediaPlayer2.Player.Rate
Future<DBusMethodResponse> getRate() async {
return DBusMethodSuccessResponse([DBusDouble(player.speed)]);
return DBusMethodSuccessResponse([DBusDouble(1)]);
}

/// Sets property org.mpris.MediaPlayer2.Player.Rate
Future<DBusMethodResponse> setRate(double value) async {
player.setSpeed(value);
player.setPlaybackRate(value);
return DBusMethodSuccessResponse();
}

Expand Down Expand Up @@ -104,19 +104,19 @@ class Player_Interface extends DBusObject {

/// Gets value of property org.mpris.MediaPlayer2.Player.Volume
Future<DBusMethodResponse> getVolume() async {
return DBusMethodSuccessResponse([DBusDouble(player.volume)]);
return DBusMethodSuccessResponse([DBusDouble(playback.volume)]);
}

/// Sets property org.mpris.MediaPlayer2.Player.Volume
Future<DBusMethodResponse> setVolume(double value) async {
player.setVolume(value);
playback.setVolume(value);
return DBusMethodSuccessResponse();
}

/// Gets value of property org.mpris.MediaPlayer2.Player.Position
Future<DBusMethodResponse> getPosition() async {
return DBusMethodSuccessResponse([
DBusInt64(player.position.inMicroseconds),
DBusInt64((await player.getDuration())?.inMicroseconds ?? 0),
]);
}

Expand Down Expand Up @@ -188,7 +188,7 @@ class Player_Interface extends DBusObject {

/// Implementation of org.mpris.MediaPlayer2.Player.PlayPause()
Future<DBusMethodResponse> doPlayPause() async {
player.playing ? player.pause() : player.play();
player.state == PlayerState.playing ? player.pause() : player.resume();
return DBusMethodSuccessResponse();
}

Expand All @@ -202,7 +202,7 @@ class Player_Interface extends DBusObject {

/// Implementation of org.mpris.MediaPlayer2.Player.Play()
Future<DBusMethodResponse> doPlay() async {
player.play();
player.resume();
return DBusMethodSuccessResponse();
}

Expand Down
2 changes: 1 addition & 1 deletion lib/provider/AudioPlayer.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:just_audio/just_audio.dart';

final audioPlayerProvider = Provider<AudioPlayer>((ref) {
return AudioPlayer();
Expand Down
Loading

0 comments on commit f896f65

Please sign in to comment.