gpt4 book ai didi

javascript - 如何使用 Expo AV 重播音轨

转载 作者:行者123 更新时间:2023-12-05 04:49:37 31 4
gpt4 key购买 nike

我正在使用 React native、aws 和 Expo 开发音乐应用程序。我正在使用 Expo AV 库播放音频文件。我无法让歌曲在结束后自动重播。

以下是我对此的尝试。

失败的方法:

  1. 我看到一个 didjustFinish bool 变量。我尝试在音频播放完毕后将其重置为 true,然后我可以 await sound.playAsync(); 但它似乎不起作用

  2. 我尝试将 durationMillis 与 playableDurationMillis 匹配 - 如果它们相等,则调用 await sound.playAsync();。这也行不通。

    import React, { useContext, useEffect, useState } from 'react';
import { Text, Image, View, TouchableOpacity } from 'react-native';
import { AntDesign, FontAwesome } from "@expo/vector-icons";
import { API, graphqlOperation } from 'aws-amplify';

import styles from './styles';
import { Song } from "../../types";
import { Sound } from "expo-av/build/Audio/Sound";

import { AppContext } from '../../AppContext';
import { getSong } from "../../src/graphql/queries";

const PlayerWidget = () => {

const [song, setSong] = useState(null);
const [sound, setSound] = useState<Sound | null>(null);
const [isPlaying, setIsPlaying] = useState<boolean>(true);
const [duration, setDuration] = useState<number | null>(null);
const [position, setPosition] = useState<number | null>(null);
const [finish, setFinish] = useState<boolean>(true);

const { songId } = useContext(AppContext);



useEffect(() => {
const fetchSong = async () => {
try {
const data = await API.graphql(graphqlOperation(getSong, { id: songId }))
setSong(data.data.getSong);
} catch (e) {
console.log(e);
}
}

fetchSong();
}, [songId])

const onPlaybackStatusUpdate = (status) => {
setIsPlaying(status.isPlaying);
setDuration(status.durationMillis);
setPosition(status.positionMillis);
setFinish(status.didJustFinish);
// console.log(finish);
console.log(status);
}

const playCurrentSong = async () => {

if (song.artist.length > 10) {
song.artist = song.artist.substring(0, 6) + "...";
}

if (song.title.length > 8) {
song.title = song.title.substring(0, 5) + "...";
}
if (sound) {
await sound.unloadAsync();
}

const { sound: newSound } = await Sound.createAsync(
{ uri: song.uri },
{ shouldPlay: isPlaying },
onPlaybackStatusUpdate
)

setSound(newSound)
}

useEffect(() => {
if (song) {
playCurrentSong();
}
}, [song])

const onPlayPausePress = async () => {
if (!sound) {
return;
}
if (isPlaying) {
await sound.pauseAsync();
}

else {
await sound.playAsync();
}

if (finish) {
await sound.playAsync();
}


}

const getProgress = () => {
if (sound === null || duration === null || position === null) {
return 0;
}

return (position / duration) * 100;
}

if (!song) {
return null;
}


return (
<View style={styles.container}>
<View style={[styles.progress, { width: `${getProgress()}%` }]} />
<View style={styles.row}>
<Image source={{ uri: song.imageUri }} style={styles.image} />
<View style={styles.rightContainer}>
<View style={styles.nameContainer}>
<Text style={styles.title}>{song.title}</Text>
<Text style={styles.artist}>{song.artist}</Text>
</View>

<View style={styles.iconsContainer}>
<AntDesign name="hearto" size={20} color={'white'} />
<TouchableOpacity onPress={onPlayPausePress}>
<AntDesign name={isPlaying ? 'pausecircleo' : 'playcircleo'} size={25} color={'white'} />
</TouchableOpacity>

</View>

</View>

</View>

</View>
)
}

export default PlayerWidget;

最佳答案

Have a look at the docs

有几点需要注意:

轨道播放一次后,再次调用 play 将不会有任何效果。但是,您可以调用 sound.replayAsync() 来重新启动音轨。

您可以让声音循环播放,以便它在结束时自动重新启动,方法是使用(引用文档):

playbackObject.setIsLoopingAsync(值)这相当于 playbackObject.setStatusAsync({ isLooping: value })

您需要重构播放/暂停方法以更好地处理不同的情况。例如,如果它已完成但仍要播放(可能会尝试调用 replayAsync 而不是 playAsync)。

另一个想法是,如果轨道已完成但仍打算播放,则重新开始轨道。所以如果你不打算使用循环,你可以删除条件

     if (finish) {
await sound.playAsync();
}

并将其放入正在观看“完成”的 useEffect 中。我想使用循环标志更容易。

关于javascript - 如何使用 Expo AV 重播音轨,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67552738/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com