npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mobile-rn-sound-player

v0.0.6

Published

A helper module to play sound in Redux

Downloads

6

Readme

mobile-rn-sound-player

Redux/Saga wrapper for react-native-sound component.

Version 0.0.6, 2018/09/14

Module Public Interfaces

Constants

import { constants as soundPlayerConstants } from 'mobile-rn-sound-player'

General:

  NAME                    - component name (for reducer)

Pre-defined pathes

  PATH_BUNDLE             - main bundle path
  PATH_DOCUMENT           - document path
  PATH_DATA               - path for data (inter-session) files 
  PATH_TEMP               - path for temporary (session) files

Notification actions:

  ON_ERROR                - action invoked on processing error

Error codes:

  ERROR_NOT_MOUNTED       - component was not properly initialized
  ERROR_SOURCE_URI        - Sound source is either not specified or not accessible 
                            (details: { uri, basePath})
  ERROR_PLAYBACK          - generic playback error

Action Creators

import { actions as soundPlayerActions } from 'mobile-rn-sound-player'
 
Init/Shut

/**
 * Initializes component (should be called first)
 * @param options.updateFrequency update period for current pos in ms
 * @param options.logLevel logging level (0 - no debug info, default; 1; 2 - wordy log)
 */
const mountRequest = (options) => ({ type: constants.MOUNT_REQUEST, options });

/**
 * Shutdowns component
 */
const unmountRequest = () => ({ type: constants.UNMOUNT_REQUEST });

Start/Stop/Pause/Set Position/Set Volume

/**
 * Starts playback
 * @param source.uri sound file name or http url (required)
 * @param source.basePath path (if 'uri' is a file, may contain special path PATH_(...))
 * @param options.paused initial paused state (by default isPaused = false)
 * @param options.repeat repetition counter (-1 for infinite loop, 1 by default)
 * @param options.pos initial position in secs (0.0 by default)
 * @param options.volume initial volume (0.0 - 1.0, 1.0 by default)
 */
const startRequest = (source, options = { paused: false, repeat: 1, pos : 0.0, 
                                          volume: { mute: false, level: 1.0 }}) => ({
  type: constants.START_REQUEST,
  source,
  options
});

/**
 * Stops playback
 * @param success false if stopped by error, true otherwise (true by default)
 */
const stopRequest = (success = true) => ({ type: constants.STOP_REQUEST, success });

/**
 * Pauses/Resumes playback
 * @param paused true to set paused state, false to continue playback, 
                 undefined to revert current state
 */
const pauseRequest = (paused) => ({ type: constants.PAUSE_REQUEST, paused });

/**
 * Sets position within file
 * @param pos position in secs (0 <= pos < duration)
 */
const setPosRequest = (pos = 0.0) => ({ type: constants.SET_POS_REQUEST, pos });

/**
 * Sets volume
 * @param volume volume descriptor
 */
const setVolumeRequest = (volume = { mute: false, level: 1.0} ) => ({ 
  type: constants.SET_VOLUME_REQUEST, 
  volume
});
 

Selectors

import { selectors as soundPlayerSelectors } from 'mobile-rn-sound-player'

soundPlayerSelectors.isMounted()        - true if component is ready for recording (mounted)
soundPlayerSelectors.isPlaying()        - true if playback is in progress (between start & stop requests)
soundPlayerSelectors.isPaused()         - true if playback is paused (isPlaying is 'true')
soundPlayerSelectors.getCurrentTime()   - current time in secs [Real Number]
soundPlayerSelectors.getInfo()          - descriptor of the last loaded sound *
soundPlayerSelectors.getDuration()      - duration in secs of the last loaded sound
soundPlayerSelectors.getVolume()        - volume descriptor, e.g. { mute: false, level: 1.0 }
soundPlayerSelectors.getError()         - last error descriptor **

// * Info object:

  const defaultInfo = {
    uri: '',                    // file uri
    basePath: '',               // base path (if applicable)
    size: 0.0,                  // file size in bytes, -1 for http source
    duration: 0.0               // sound duration in secs (if available)
  };

// ** Error object:

  const error = { 
    errCode: 0,                 // error code, one of soundPlayerConstants.ERROR_(...) constants
    details: {                  // arbitrary additional information
      error: new Error(message) // default Error object with optional message
      ...                       // additional error-specific data
    } 
  };

Getting started

Step 1. Install mobile-rn-sound-player

$ npm install mobile-rn-sound-player --save
# or with yarn
$ yarn add mobile-rn-sound-player

Step 2. Install react-native-sound

If you have already installed react-native-sound as a dependency for your project you can skip this step. Otherwise please follow instructions provided here https://github.com/zmxv/react-native-sound.

Project Integration (2 steps)

Step 1. Add sound player's reducer to the root reducer

// rootReducer.js

import { combineReducers } from 'redux';
import { reducer as soundPlayerReducer, 
         constants as soundPlayerConstants } from 'mobile-rn-sound-player';

const rootReducer = combineReducers({
  ...
   [soundPlayerConstants.NAME]: soundPlayerReducer,
  ...
});

export default rootReducer;

Step 2. Initialize & run sound player's saga

// rootSaga.js

import { all, call } from 'redux-saga/effects';
import { saga as soundPlayerSaga } from 'mobile-rn-sound-player';

export default function* rootSaga() {
  yield all([
    ...
    call(soundPlayerSaga),
    ...
  ]);
}

or

// rootSaga.js

import { all, call } from 'redux-saga/effects';
import soundPlayer from 'mobile-rn-sound-player';

export default function* rootSaga() {
  yield all([
    ...
    call(soundPlayer.saga),
    ...
  ]);
}

Usage in React Native components

Step 1. Screen

// components/VoicePlayer/VoicePlayerContainer.js

import VoicePlayer from './VoicePlayer';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { selectors as soundPlayerSelectors, 
         actions as soundPlayerActions } from 'mobile-rn-sound-player';

function mapStateToProps(state) {
  return {
    isPlaying: soundPlayerSelectors.isPlaying(state),
    isPaused: soundPlayerSelectors.isPaused(state),
    currentTime: soundPlayerSelectors.getCurrentTime(state),
    ...
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    mountRequest: soundPlayerActions.mountRequest,
    unmountRequest: soundPlayerActions.unmountRequest,
    startRequest: soundPlayerActions.startRequest,
    stopRequest: soundPlayerActions.stopRequest,
    pauseRequest: soundPlayerActions.pauseRequest,
    ...
  }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(VoicePlayer);
// components/VoicePlayer/VoicePlayer.js

import { constants as soundPlayerConstants } from 'mobile-rn-sound-player';

class VoicePlayer extends Component {

  static propTypes = {
    ...
    isPlaying: PropTypes.bool,
    isPaused: PropTypes.bool,
    currentTime: PropTypes.number,
    mountRequest: PropTypes.func.isRequired,
    unmountRequest: PropTypes.func.isRequired,
    startRequest: PropTypes.func.isRequired,
    stopRequest: PropTypes.func.isRequired,
    pauseRequest: PropTypes.func.isRequired,
    ...
  };

  static defaultProps = {
    ...
    isPlaying: false,
    isPaused: false,
    currentTime: 0.0
  };

  componentDidMount() {
    // Note, that 1) the component will be drawn first time with the default props,
    // 2) It is more safe to initialize recorder somewhere earlier than here on componentDidMount()
    const options = { updateFrequency: 150, logLevel: 1 }; // optional, if differs from defaults
    this.props.mountRequest(options);
  }

  componentWillUnmount() {
    this.props.unmountRequest();
  }

  ...

  handleStart = () => {
    const source = {
      uri: fileName,                                // file name (or url)
      basePath: soundPlayerConstants.PATH_DOCUMENT  // base path (required for files, n/a for urls)
    };
    const options = {                               // optional, if differs from defaults
      volume: { level: 0.5 }                        // set volume level 0.5, mute = false
    }
    this.props.startRequest(source, options);
  }

  handleStop = () => {
    this.props.stopRequest();
  }

  handlePause = () => {
    this.props.pauseRequest();
  }

  render() {
    ...
  }
}
...

export default VoicePlayer;

Step 2. Saga

// saga/onSoundPlayer.js

import { Alert } from 'react-native';
import { takeLatest, call, select, put, all } from 'redux-saga/effects';
import { constants as soundPlayerConstants } from 'mobile-rn-sound-player';

function* _onSoundError(action) {
  try {
    const { errCode, details } = action.error;
    switch (errCode) {
      case soundPlayerConstants.ERROR_SOURCE_URI:
        Alert.alert('Attention',
                    `Sound source is either not found or not accessible (${details.uri})`,
                    [{text: 'OK'}], { cancelable: false });
        break;
    }
  }
  catch (err) {
  }
}

export function* watchOnSoundError() {
  yield takeLatest(soundPlayerConstants.ON_ERROR, _onSoundError);
}

// Note: you could place soundPlayer.saga here in order to have all
//       sound player's sagas in one place
export function* watchOnSoundPlayer() {
  yield all([
    call(watchOnSoundError)
  ]);
}