tanguyantoine / react-native-music-control

Display and manage media controls on lock screen and notification center for iOS and Android.
https://www.npmjs.com/package/react-native-music-control
MIT License
697 stars 264 forks source link

IOS background mode Play pause controls are disabled but seek bar is moving. #413

Open singhiam opened 1 year ago

singhiam commented 1 year ago

Description

import React, { Component, useEffect, useState } from 'react'; import { ActivityIndicator, Animated, Platform, StyleSheet, TouchableOpacity, View, } from 'react-native'; import { connect } from 'react-redux'; import Video from 'react-native-video'; import { withTheme } from 'styled-components'; import { Actions } from 'react-native-router-flux'; import { TFunction, withTranslation } from 'react-i18next'; import MusicControl, { Command } from 'react-native-music-control'

import RewindBtn from './components/RewindBtn/RewindBtn'; import MainBtn from '../_common/buttons/MainBtn/MainBtn'; import PlayBtn from '../_common/buttons/_player/PlayBtn/PlayBtn'; import PlayerSlider from './components/PlayerSlider/PlayerSlider'; import PauseBtn from '../_common/buttons/_player/PauseBtn/PauseBtn'; import DecreaseBtn from '../_common/buttons/_player/DecreaseBtn/DecreaseBtn'; import IncreaseBtn from '../_common/buttons/_player/IncreaseBtn/IncreaseBtn';

import { getActivity } from '../../redux/actions/user';

import { getData } from '../../querys'; import { getFormattedDuration } from '../../helpers/timeHelpers';

import { ITheme } from '../../theme/types/themeTypes'; import { IMeditation } from '../../types/meditationTypes'; import { getItems } from '../../redux/actions/app';

const RN_FS = require('react-native-fs');

export interface Props { app: any; network: any; user: any; data: IMeditation; t: TFunction; theme: ITheme; dispatch: any; active: boolean; download: boolean; courseId?: number; scrollBottom: () => void; }

const AudioController = (props: Props) => { let player: any;

const [pause, setPause] = useState(true); const [muted, setMuted] = useState(false); const [loader, setLoader] = useState(false); const [loaded, setLoaded] = useState(false); const [left, setLeft] = useState('--:--'); const [totalLength, setTotalLength] = useState(1); const [activity_id, setActivity_id] = useState(''); const [show_loader, setShowLoader] = useState(true); const [currentPosition, setCurrentPosition] = useState(0); const [loaded_for_ios, setLoadedforIos] = useState(false); const [totalLengthFormat, setTotalLengthFormat] = useState('00:00'); const [currentTimeFormat, setCurrentTimeFormat] = useState('00:00'); const [file, setFile] = useState(''); const [fadeAnim, setFadeAnim] = useState(new Animated.Value(0)); const [marginTopAnim, setMarginTopAnim] = useState(new Animated.Value(20)); const [file_bg, setFileBg] = useState(props.data.sound_file_with_bg_music); useEffect(() => { MusicControl.enableBackgroundMode(true); MusicControl.handleAudioInterruptions(true); // Basic Controls

MusicControl.enableControl('play', true)
MusicControl.enableControl('pause', true)
MusicControl.enableControl('stop', true);
MusicControl.enableControl('nextTrack', false)
MusicControl.enableControl('previousTrack', false)
MusicControl.on(Command.play, () => {
  // player.actions.play()
  console.log('Play Tapped')
  //onPlay();
  setPause(false);
})

MusicControl.on(Command.pause, () => {
  // player.actions.pause()
  // onPause();
  console.log('Pause Tapped');
  setPause(true);
})

// MusicControl.on(Command.stop, () => {
//   // player.actions.pause()
//   onPause();
//   setPause
// })

}, [])

useEffect(() => { if (pause) { MusicControl.updatePlayback({ state: MusicControl.STATE_PAUSED, elapsedTime: currentPosition }) // MusicControl.enableControl('play', false) MusicControl.enableControl('pause', true) } else { MusicControl.updatePlayback({ state: MusicControl.STATE_PLAYING, elapsedTime: currentPosition }) MusicControl.setNowPlaying({ title: 'MyMedi', duration: totalLength, artwork: 'https://i.imgur.com/e1cpwdo.png', }); MusicControl.enableControl('pause', false) } }, [pause])

const setDuration = (data) => { setTotalLength(Math.floor(data.duration)); setTotalLengthFormat(getFormattedDuration(data.duration)) setLoaded(true); }

const setTime = (data) => { if (data.currentTime < 0) { setShowLoader(false); }

const currentTime = Math.floor(data.currentTime);
const leftTime = totalLength - currentTime;

// this.setState({
//   currentPosition: currentTime,
//   currentTimeFormat: getFormattedDuration(currentTime),
//   left: getFormattedDuration(leftTime),
// });
setCurrentPosition(currentTime);
setCurrentTimeFormat(getFormattedDuration(currentTime));
setLeft(getFormattedDuration(leftTime))
MusicControl.updatePlayback({
  elapsedTime: currentTime
})

}

const seek = (time) => { time = Math.round(time); player && player.seek(time);

// this.setState({ currentPosition: time });
setCurrentPosition(time)

}

const increase = () => { // const currentPosition = currentPosition; // const totalLength = totalLength; const time = currentPosition + 10;

if (time > totalLength) {
  player && player.seek(totalLength);
} else {
  player && player.seek(time);
  // this.setState({ currentPosition: time });
  setCurrentPosition(time);
}

}

const decrease = () => { const time = currentPosition - 10; player && player.seek(time); // this.setState({ currentPosition: time }); setCurrentPosition(time); }

const createActivity = async () => { const data = { api_token: props.user.api_token, item_id: props.data.id + '', }; const response = await getData('user/activity/create', 'POST', data); // this.setState({ activity_id: response.activity_id }); setActivity_id(response.activity_id); }

const moveToAfterScreen = async () => { const data = { api_token: props.user.api_token, activity_id: activity_id + '', is_complete: true, };

if (!props.network.isConnected) {
  Actions.after_play({ data: props.data, download: props.download });
  return;
}

const response = await getData('user/activity/edit', 'POST', data);

if (response.status) {
  props.dispatch(getActivity(props.user.api_token));
}
Actions.after_play({ data: props.data, download: props.download });

}

const finishCourseItem = async () => { if (!props.network.isConnected) return;

props.dispatch(getItems(props.user.api_token));

if (props.active) {
  const data = {
    api_token: props.user.api_token,
    item_id: props.data.id,
    course_id: props.courseId,
  };
  const response = await getData('courses/progress/update', 'POST', data);

  if (response.status) {
    props.dispatch({
      type: 'GET_COURSES',
      api_token: props.user.api_token,
    });
  }
}

}

const show = () => { // let { loaded } = this.state; if (loaded) { // this.setState({ show_loader: false }); setShowLoader(false); } else { // this.setState({ show_loader: false }); setShowLoader(false); } Animated.timing(marginTopAnim, { toValue: 0, duration: 2000, useNativeDriver: false, }).start(); Animated.timing(fadeAnim, { toValue: 1, duration: 2000, useNativeDriver: false, }).start(); }

const subscribe = () => { Actions.subscribe({ image: props.data.image_file }); }

const onPlay = () => { // this.setState({ pause: false }); setPause(false); show(); createActivity(); props.scrollBottom(); MusicControl.setNowPlaying({ title: 'MyMedi', duration: totalLength, artwork: 'https://i.imgur.com/e1cpwdo.png', }); // MusicControl.enableControl('play', true) MusicControl.enableControl('pause', false) }

const onPause = () => { // this.setState({ pause: true }); setPause(true); }

const onSlidingComplete = (value) => { seek(value); // this.setState({ pause: false }); setPause(false) }

const getIsLock = () => { const { user } = props; const isAccess = user.access || user.is_vip || user.access_from_store;

if (isAccess) return !isAccess;
else return !props.data.is_free;

}; // let { file, file_bg, loader, show_loader } = this.state; const { duration } = props.data; const { theme, t } = props;

const styles = createStyle(theme);

const isLock = getIsLock(); let fileRef = file; let file_bgRef = file_bg;

props.download ? (fileRef = 'file://' + RN_FS.DocumentDirectoryPath + '/meditation/' + fileRef) : null;

props.download ? (file_bgRef = 'file://' + RN_FS.DocumentDirectoryPath + '/meditation/' + file_bgRef) : null;

const file_to_play = props.app.bg_music ? file_bgRef : file;

// const { pause, fadeAnim, marginTopAnim, left, currentPosition, muted } = this.state;

return ( <View style={{ flex: 1, width: '100%' }}> <Video muted={muted} paused={pause} audioOnly={true} playInBackground={true} ignoreSilentSwitch="ignore" source={{ uri: file_to_play }} controls={Platform.OS == 'ios'} onProgress={data => setTime(data)} playWhenInactive={true} mixWithOthers="inherit" ref={ref => { player = ref; }} onLoad={data => { setDuration(data); MusicControl.setNowPlaying({ title: 'MyMedi', duration: data.duration, artwork: 'https://i.imgur.com/e1cpwdo.png', }); }} onEnd={async () => { await finishCourseItem(); await moveToAfterScreen(); MusicControl.resetNowPlaying() MusicControl.stopControl(); }} />

onSlidingComplete(value)} onSlidingStart={() => onPause()} /> {loader && ( )} {!loader && !isLock ? ( increase()} text={` +10${t('common.time.sec')}`} icon={} revert={!theme.isRTL} /> onPlay() : () => onPause()} > {pause ? : } decrease()} text={` -10${t('common.time.sec')}`} icon={} revert={theme.isRTL} /> ) : ( subscribe()} withLoading={false} />
    )}
  </View>
</View>

); }

const mapStateToProps = (state: any) => state;

export default connect(mapStateToProps)(withTheme(withTranslation()(AudioController)));

const createStyle = theme => { return StyleSheet.create({ header_container: { alignItems: 'center', width: '100%', justifyContent: 'center', }, controller: { flexDirection: theme.isRTL ? 'row' : 'row-reverse', alignItems: 'center', width: '100%', justifyContent: 'center', }, }); };

  1. Platform ?

    • [x] iOS
    • [ ] Android
3. Device - [ ] Simulator - [x] Real device I am using React-Native-Video Player with "'react-native-music-control" but in background mode Play pause controls are disabled. Seek bar moving good, Artwork is also showing but Player play , pause controls are not working.
singhiam commented 1 year ago

@bradleyflood Can you please help me here.

singhiam commented 1 year ago

IMG_9535

bradfloodx commented 1 year ago

Hi @singhiam, I recommend switching over to https://github.com/doublesymmetry/react-native-track-player