diff --git a/index.ts b/index.ts
index f725a6a..f16aef1 100644
--- a/index.ts
+++ b/index.ts
@@ -1,6 +1,9 @@
import 'react-native-gesture-handler';
import { AppRegistry } from 'react-native';
+import TrackPlayer from 'react-native-track-player';
import App from './src/components/App';
import { name as appName } from './app.json';
+import PlaybackService from './src/utility/PlaybackService';
AppRegistry.registerComponent(appName, () => App);
+TrackPlayer.registerPlaybackService(() => PlaybackService);
\ No newline at end of file
diff --git a/ios/JellyfinAudioPlayer.xcodeproj/project.pbxproj b/ios/JellyfinAudioPlayer.xcodeproj/project.pbxproj
index 3c739d6..382b280 100644
--- a/ios/JellyfinAudioPlayer.xcodeproj/project.pbxproj
+++ b/ios/JellyfinAudioPlayer.xcodeproj/project.pbxproj
@@ -288,17 +288,21 @@
TargetAttributes = {
00E356ED1AD99517003FC87E = {
CreatedOnToolsVersion = 6.2;
+ DevelopmentTeam = HD2D35G9Y4;
TestTargetID = 13B07F861A680F5B00A75B9A;
};
13B07F861A680F5B00A75B9A = {
+ DevelopmentTeam = HD2D35G9Y4;
LastSwiftMigration = 1120;
};
2D02E47A1E0B4A5D006451C7 = {
CreatedOnToolsVersion = 8.2.1;
+ DevelopmentTeam = HD2D35G9Y4;
ProvisioningStyle = Automatic;
};
2D02E48F1E0B4A5D006451C7 = {
CreatedOnToolsVersion = 8.2.1;
+ DevelopmentTeam = HD2D35G9Y4;
ProvisioningStyle = Automatic;
TestTargetID = 2D02E47A1E0B4A5D006451C7;
};
@@ -584,6 +588,7 @@
baseConfigurationReference = 8DAD3DCD6450C4255A20940E /* Pods-JellyfinAudioPlayer-JellyfinAudioPlayerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
+ DEVELOPMENT_TEAM = HD2D35G9Y4;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@@ -608,6 +613,7 @@
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
COPY_PHASE_STRIP = NO;
+ DEVELOPMENT_TEAM = HD2D35G9Y4;
INFOPLIST_FILE = JellyfinAudioPlayerTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -629,6 +635,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = HD2D35G9Y4;
ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
@@ -656,6 +663,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = HD2D35G9Y4;
INFOPLIST_FILE = JellyfinAudioPlayer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
OTHER_LDFLAGS = (
@@ -681,6 +689,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
+ DEVELOPMENT_TEAM = HD2D35G9Y4;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "JellyfinAudioPlayer-tvOS/Info.plist";
@@ -710,6 +719,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = HD2D35G9Y4;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "JellyfinAudioPlayer-tvOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -736,6 +746,7 @@
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
+ DEVELOPMENT_TEAM = HD2D35G9Y4;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "JellyfinAudioPlayer-tvOSTests/Info.plist";
@@ -764,6 +775,7 @@
CLANG_WARN_SUSPICIOUS_MOVE = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DEVELOPMENT_TEAM = HD2D35G9Y4;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = "JellyfinAudioPlayer-tvOSTests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
diff --git a/ios/JellyfinAudioPlayer/Info.plist b/ios/JellyfinAudioPlayer/Info.plist
index 1a546c2..c385a06 100644
--- a/ios/JellyfinAudioPlayer/Info.plist
+++ b/ios/JellyfinAudioPlayer/Info.plist
@@ -42,6 +42,7 @@
UIBackgroundModes
audio
+ processing
UILaunchStoryboardName
LaunchScreen
diff --git a/src/components/App.tsx b/src/components/App.tsx
index caf853e..f336983 100644
--- a/src/components/App.tsx
+++ b/src/components/App.tsx
@@ -14,6 +14,15 @@ export default class App extends Component {
async componentDidMount() {
await TrackPlayer.setupPlayer();
+ await TrackPlayer.updateOptions({
+ capabilities: [
+ TrackPlayer.CAPABILITY_PLAY,
+ TrackPlayer.CAPABILITY_PAUSE,
+ TrackPlayer.CAPABILITY_SKIP_TO_NEXT,
+ TrackPlayer.CAPABILITY_SKIP_TO_PREVIOUS,
+ TrackPlayer.CAPABILITY_STOP,
+ ]
+ });
this.setState({ isReady: true });
}
diff --git a/src/screens/Player/components/MediaControls.tsx b/src/screens/Player/components/MediaControls.tsx
index 1b879ba..ac2ef42 100644
--- a/src/screens/Player/components/MediaControls.tsx
+++ b/src/screens/Player/components/MediaControls.tsx
@@ -23,10 +23,12 @@ const Container = styled.View`
const Buttons = styled.View`
flex-direction: row;
align-items: center;
+ justify-content: space-between;
+ width: 100%;
`;
const Button = styled.View`
- margin: 20px;
+ margin: 20px 40px;
`;
export default function MediaControls() {
diff --git a/src/screens/Player/components/NowPlaying.tsx b/src/screens/Player/components/NowPlaying.tsx
index 8dd819b..2fb1d50 100644
--- a/src/screens/Player/components/NowPlaying.tsx
+++ b/src/screens/Player/components/NowPlaying.tsx
@@ -18,16 +18,11 @@ const Artwork = styled.Image`
export default function NowPlaying() {
const track = useCurrentTrack();
- // GUARD: Don't render anything if nothing is playing
- if (!track) {
- return null;
- }
-
return (
-
- {track.artist}
- {track.title}
+
+ {track?.artist}
+ {track?.title}
);
}
\ No newline at end of file
diff --git a/src/utility/PlaybackService.ts b/src/utility/PlaybackService.ts
new file mode 100644
index 0000000..848af26
--- /dev/null
+++ b/src/utility/PlaybackService.ts
@@ -0,0 +1,32 @@
+/**
+* This is the code that will run tied to the player.
+*
+* The code here might keep running in the background.
+*
+* You should put everything here that should be tied to the playback but not the UI
+* such as processing media buttons or analytics
+*/
+
+import TrackPlayer from 'react-native-track-player';
+
+export default async function() {
+ TrackPlayer.addEventListener('remote-play', () => {
+ TrackPlayer.play();
+ });
+
+ TrackPlayer.addEventListener('remote-pause', () => {
+ TrackPlayer.pause();
+ });
+
+ TrackPlayer.addEventListener('remote-next', () => {
+ TrackPlayer.skipToNext();
+ });
+
+ TrackPlayer.addEventListener('remote-previous', () => {
+ TrackPlayer.skipToPrevious();
+ });
+
+ TrackPlayer.addEventListener('remote-stop', () => {
+ TrackPlayer.destroy();
+ });
+}
\ No newline at end of file