12-3 RN之音频播放

302 阅读2分钟

12-3 音频播放

在本节中,我们将学习如何在 React Native 项目中实现音频播放功能。

安装依赖

React Native 官方没有内置音频播放组件,因此需要安装第三方依赖 react-native-sound 来实现音频播放功能:

yarn add react-native-sound

安装完成后,需要重新安装应用:

yarn android
cd ios && pod install
cd ..
yarn ios

创建音频播放器辅助函数

由于音频播放是后台服务,react-native-sound 不是一个组件库,因此我们将创建辅助函数来封装音频播放功能。创建一个 sound.ts 文件,并写入以下代码:

import Sound from 'react-native-sound';

// 在静音模式下启用播放
Sound.setCategory('Playback');

let sound: Sound;

// 初始化播放器,加载音频是一个耗时操作,因此不能在创建后立即使用
const init = (url: string) => {
  return new Promise((resolve, reject) => {
    sound = new Sound(url, '', error => {
      if (error) {
        console.log('failed to load the sound', error);
        reject(error);
      } else {
        resolve(sound);
      }
    });
  });
};

// 播放音频
const play = () => {
  return new Promise((resolve, reject) => {
    sound.play(success => {
      if (success) {
        console.log('successfully finished playing');
        resolve(sound);
      } else {
        console.log('playback failed due to audio decoding errors');
        reject();
      }
    });
  });
};

// 暂停播放
const pause = () => {
  return new Promise(resolve => {
    if (sound) {
      sound.pause(() => resolve());
    } else {
      resolve();
    }
  });
};

// 获取当前播放时间
const getCurrentTime = () => {
  return new Promise(resolve => {
    if (sound && sound.isLoaded()) {
      sound.getCurrentTime(seconds => resolve(seconds));
    } else {
      resolve(0);
    }
  });
};

// 获取音频时长
const getDuration = () => {
  if (sound) {
    return sound.getDuration();
  }
  return 0;
};

export { sound, init, play, pause, getCurrentTime, getDuration };

获取音频 URL

为了播放音频,我们需要从 API 获取音频的 URL 地址。我们通过创建接口来获取音频的 URL,并将其用于后续播放。在 model 文件夹下创建 player.ts 文件,使用 axios 来请求音频数据并初始化播放器。

import axios from 'axios';
import { Effect, Model, Reducer } from 'dva-core-ts';
import { RootState } from '.';
import { sound, init, play, getCurrentTime, getDuration } from '@/config/sound';

const REQUEST_URL = '/mock/11/show';

export interface PlayerModelState {
  id: string;
  soundUrl: string;
}

export interface PlayerModelType extends Model {
  namespace: 'player';
  state: PlayerModelState;
  reducers: {
    setState: Reducer<PlayerModelState>;
  };
  effects: {
    fetchShow: Effect;
    play: Effect;
  };
}

const initialState: PlayerModelState = {
  id: '',
  soundUrl: '',
  playState: '',
};

const PlayerModel: PlayerModelType = {
  namespace: 'player',
  state: initialState,
  reducers: {
    setState(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
  },
  effects: {
    *fetchShow(_, { call, put }) {
      const { data } = yield call(axios.get, REQUEST_URL);
      yield call(init, data.soundUrl);
      yield put({
        type: 'setState',
        payload: {
          id: data.id,
          soundUrl: data.soundUrl,
          duration: getDuration(),
        },
      });
      yield put({ type: 'play' });
    },
    *play(_, { put, call }) {
      yield put({
        type: 'setState',
        payload: { playState: 'playing' },
      });
      yield call(play);
      yield put({
        type: 'setState',
        payload: { playState: 'finish', currentTime: 0 },
      });
    },
  },
};

export default PlayerModel;

更新 Detail 页面

Detail 页面中,通过 dispatch 请求音频数据并初始化播放。在 componentDidMount 中调用 fetchShow 方法来获取音频 URL。

componentDidMount() {
  const { dispatch, route } = this.props;
  dispatch({
    type: 'player/fetchShow',
    payload: { id: route.params?.id },
  });
}

整体流程

  1. 安装依赖:安装 react-native-sound 库并配置。
  2. 创建音频播放器函数:封装音频播放、暂停、获取当前播放时间等功能。
  3. 获取音频 URL:通过 axios 请求音频 URL,并初始化音频播放器。
  4. 更新 Detail 页面:在 Detail 页面中请求音频数据并触发播放。

总结

本节中,我们学习了如何在 React Native 中播放音频,包括音频播放的初始化、播放、暂停、获取时长等功能的实现。下一节将介绍如何控制音频的进度条。