react-native - React Native Expo 开启和关闭音频
问题描述
我想在我的 react native expo 应用程序中打开和关闭声音,但是当我多次打开和关闭时,它会导致声音重叠并且我不确定是否需要设置音频状态?我似乎在这里找不到任何好的例子 - https://docs.expo.io/versions/latest/sdk/av/不确定我做错了什么,RN的新手。
如您所见,这是一个标题按钮,它必须在整个应用程序中工作,而不仅仅是一个屏幕。
这是我的零食 - https://snack.expo.io/@roshambo/sound-toggle-on-and-off
import React, { useState } from "react";
import { HeaderButton } from "react-navigation-header-buttons";
import { Ionicons } from "@expo/vector-icons";
import { Audio } from "expo-av";
const CustomHeaderButton = props => {
const [soundIcon, setSoundIcon] = useState(false);
const soundObject = new Audio.Sound();
(async () => {
await soundObject.loadAsync(require("../assets/bglaughs.mp3"), {
volume: 0.25,
isLooping: true,
shouldPlay: true,
isMuted: true
});
})();
const toggleSound = () => {
setSoundIcon(prevState => !prevState);
soundObject.setOnPlaybackStatusUpdate(this._onPlaybackStatusUpdate);
};
_onPlaybackStatusUpdate = playbackStatus => {
if (playbackStatus.isMuted) {
playSound();
} else {
stopSound();
}
};
const stopSound = async () => {
try {
await soundObject.stopAsync();
} catch (error) {
console.log("sound couldn't pause");
}
};
const playSound = async () => {
try {
await soundObject.setIsMutedAsync(false);
await soundObject.playAsync();
} catch (error) {
console.log("sound couldn't play");
}
};
return (
<HeaderButton
{...props}
IconComponent={Ionicons}
iconSize={23}
iconName={soundIcon ? "ios-volume-high" : "ios-volume-off"}
onPress={toggleSound}
/>
);
};
export default CustomHeaderButton;
更新:
这是我基于 Oleg 的回答的工作代码以及我在 redux 上的实现。
零件
import React from "react";
import { HeaderButton } from "react-navigation-header-buttons";
import { useDispatch, useSelector } from "react-redux";
import * as soundActions from "../store/actions/sound-action";
import { Ionicons } from "@expo/vector-icons";
const CustomHeaderButton = props => {
const sound = useSelector(state => state.sound.soundState);
const dispatch = useDispatch();
return (
<HeaderButton
{...props}
IconComponent={Ionicons}
iconSize={23}
iconName={sound === "playing" ? "ios-volume-high" : "ios-volume-off"}
onPress={() => {
dispatch(soundActions.toggleSound(sound));
}}
/>
);
};
export default CustomHeaderButton;
减速器
import { TOGGLE_SOUND } from "../actions/sound-action";
import { Audio } from "expo-av";
const initialState = {
soundState: "nosound"
};
export default (state = initialState, action) => {
switch (action.type) {
case TOGGLE_SOUND:
if (state.soundState === "nosound") {
(async () => {
const { sound } = await Audio.Sound.createAsync(
require("../../assets/bglaughs.mp3"),
{
shouldPlay: true,
volume: 0.25,
isLooping: true
}
);
this.sound = sound;
})();
return {
...state,
soundState: "playing"
};
} else if (state.soundState === "playing") {
(async () => {
if (this.sound !== null) {
await this.sound.pauseAsync();
}
})();
return { ...state, soundState: "donepause" };
} else if (state.soundState === "donepause") {
(async () => {
await this.sound.playAsync();
})();
return { soundState: "playing" };
}
}
return state;
};
解决方案
我为您的问题创建了零食答案:您必须注意创建声音和标志循环设置为 false 的新方法。
推荐阅读
- php - 添加类别页面发生数据库错误
- javascript - 猫头鹰旋转木马上第一项大的滑块
- ionic3 - ionic 3 应用程序中的消息发送不起作用
- reactjs - React typescript - 使用 const 调用 api 数据?
- python - Pandas 中的未命名列和 Nan
- android-studio - 在 android studio 中连接到 http://127.0.0.1 被拒绝
- node.js - ionic+firebase+elasticsearch 无法使用 elasticsearch.js 进行身份验证
- javascript - 使用 PHP 调用 API 后如何在 sessionStorage 中存储会话数据?
- reactjs - 使用 Slim 框架从 axios POST 请求中获取正文
- outlook-web-addins - Outlook Web 加载项在 OWA 中有效,但在桌面 Outlook 中的输入字段无效