【问题标题】:(React Native) update the 'fileduration' state for 'React-native-slider' upon fetching the audio file from firebase(React Native)在从 firebase 获取音频文件时更新“React-native-slider”的“fileduration”状态
【发布时间】:2020-06-08 17:32:25
【问题描述】:

TL;DR

不确定何时会获取音频文件并将其提供给轨道播放器。所以我需要一种方法来检测文件已被提取并且持续时间值现在可用的更改。我尝试过使用 Async/await,但它仍然无法按时将持续时间值传递给滑块。

我正在开发一个 RN 应用程序,它可以流式传输当前存储在我的 firebase 存储中的音频文件。我在更新滑块的maximumValue 时遇到了困难。由于歌曲需要几秒钟才能从 Firebase 中获取,因此由 react-native-track-player 给出的歌曲文件的(总)持续时间值是 undefiend 并且因此播放按钮的 onPress 函数 setState(duration) 将新的 tracklength 状态设置为undefined。这被设置为滑块的最大值,这反过来又给出了错误,如屏幕截图所示。

当TrackPlayer.getState()(来自ProgressComponent的方法)将其值更改为'playing'或'Ready'时,我该怎么做?应用程序会自动使用正确的持续时间值重新呈现,而不会给出错误。 我用过React-native-slider and React-native-Track-player

/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import { Text, View, Image, SafeAreaView, TouchableOpacity, Platform, StatusBar, Dimensions, Modal, Button } from 'react-native';
import Slider from 'react-native-slider';
import Moment from 'moment';
import DeviceInfo from 'react-native-device-info';
import { FontAwesome5, Feather, Entypo } from '@expo/vector-icons';
import { Surface, Card, Badge } from 'react-native-paper';
import TrackPlayer, { ProgressComponent, getPosition } from 'react-native-track-player';
import storage from '@react-native-firebase/storage';

export default class MusicPlayer extends ProgressComponent {

    componentWillMount() {
        TrackPlayer.setupPlayer().then(async () => {
            await TrackPlayer.add({
                // url: 'https://sampleswap.org/mp3/artist/5101/Peppy--The-Firing-Squad_YMXB-160.mp3',
                url: (await storage().ref('Songs/01 - Luck Aazma - www.downloadming.com.mp3').getDownloadURL()).toString(),
            });
        }
        ).then(console.log('aaaaaaaaaaaaaaaaaaaaaaa ' + this.getS().then(res => console.log(res))));
        // .then(async () => {
        //     var dur = (await TrackPlayer.getDuration()).toString();
        //     this.setState({ trackLength: dur });
        // });
        // const temp = await TrackPlayer.getState();
        // if (temp === TrackPlayer.STATE_READY) { console.log('its ready here') }
    }
    // componentDidMount() {
    //     this.interval = setInterval(
    //         () => {
    //             this.forceUpdate;
    //         }, 3500
    //     );
    // }
    // componentWillUnmount() {
    //     clearInterval(this.interval);
    // }
    constructor(props) {
        super(props);
        this.state = {
            trackLength: 300,
            timeElapsed: '0:00',
            timeRemaining: '5:00',
            optionsVisible: false,
            curr_time: 0,
            isPlaying: false,
            t_state: this.getS(),
        };
    }
    seekTime = seconds => {
        this.setState({ timeElapsed: Moment.utc(seconds * 1000).format('m:ss') });
        TrackPlayer.seekTo(seconds);
        this.setState({ timeRemaining: Moment.utc((this.state.trackLength - seconds) * 1000).format('m:ss') });
    };
    setCurr = seconds => {
        return Moment.utc(seconds * 1000).format('m:ss');
    };
    getS = async () => {
        return await TrackPlayer.getState();
    }
    render() {
        return (
            <SafeAreaView style={{ backgroundColor: '#2d545e', flex: 1, paddingTop: (DeviceInfo.hasNotch && Platform.OS === 'android') ? StatusBar.currentHeight : 0 }}>
                <View style={{ margin: 3, flex: 1 }}>
                    <TouchableOpacity
                        style={{ alignSelf: 'flex-end', marginRight: 10 }}
                        onPress={this.toggleOverlay} >
                        <Entypo name="dots-three-vertical" size={24} color="white" />
                    </TouchableOpacity>
                    {/* playlist name and album name */}
                    <View style={{ alignItems: 'center', marginTop: -25 }}>
                        <Text style={{ color: '#FFFFFF', fontSize: 10 }}>PLAYLIST</Text>
                        <Text style={{ color: '#FFFFFF', fontFamily: 'sans-serif', fontWeight: '500' }}>Album_name_here</Text>
                    </View>

                    {/* song image/ thumbnail zone */}
                    <Surface raised style={{ marginTop: 30, height: 200, width: 200, alignSelf: 'center', elevation: 50, borderRadius: 30 }}>
                        <Image source={{ uri: 'https://a10.gaanacdn.com/images/albums/61/161/crop_480x480_161.jpg' } || require('../../assets/images/temp.jpeg')} style={{ height: 200, width: 200, borderRadius: 30, alignSelf: 'center' }} />
                    </Surface>

                    {/* song name and artist name */}
                    <View style={{ marginTop: 25, flexDirection: 'column', alignItems: 'center' }}>
                        <Text style={{ color: '#FFFFFF', fontFamily: 'sans-serif', fontWeight: 'bold', fontSize: 20 }}>Song_Name_here</Text>
                        <Text style={{ color: '#FFFFFF', fontFamily: 'sans-serif', fontWeight: '500', marginTop: 3 }}>artist_name_here</Text>
                    </View>

                    {/* slider component only */}
                    <View style={{ flexDirection: 'column', alignItems: 'center', marginTop: 8 }}>
                        <Slider
                            minimumValue={0}
                            value={this.state.position}
                            animationType="timing"
                            maximumValue={this.state.trackLength}
                            trackStyle={{ width: Dimensions.get('screen').width - 50, height: 4 }}
                            thumbStyle={{ height: 20, width: 20, backgroundColor: '#fff' }}
                            thumbTouchSize={{ width: 100, height: 40 }}
                            minimumTrackTintColor="#000000"
                            onSlidingComplete={seconds => { console.log(seconds); this.seekTime(seconds); }}
                        />
                        <View style={{ width: Dimensions.get('screen').width - 35, backgroundColor: '#', flexDirection: 'row', justifyContent: 'space-between' }}>
                            <Text style={{ flex: 1 }}>{this.setCurr(this.state.position)}</Text>
                            <Text style={{ alignSelf: 'flex-end' }}>{this.setCurr(this.state.trackLength)}</Text>
                        </View>
                    </View>

                    {/* repeat, back, play, forward and shuffle button */}
                    <View style={{ width: '95%', height: 70, backgroundColor: '#', alignSelf: 'center', margin: 15, flexDirection: 'row' }}>
                        <TouchableOpacity style={{ flex: 1, height: 30, width: 10, alignSelf: 'center', justifyContent: 'space-between', alignItems: 'center' }}>
                            <Feather
                                name="repeat"
                                size={30}
                                color="#000000"
                                style={{ alignItems: 'center' }}
                            />
                        </TouchableOpacity>
                        <TouchableOpacity style={{ flex: 1, height: 30, width: 10, alignSelf: 'center', justifyContent: 'space-between' }} onPress={() => TrackPlayer.skipToPrevious()}>
                            <FontAwesome5 name="backward" size={32} color="#242320" style={{ alignSelf: 'center' }} />
                        </TouchableOpacity>
                        {
                            // this.state.t_state === TrackPlayer.STATE_READY && 
                            !this.state.isPlaying && <TouchableOpacity
                                style={{ flex: 1, height: 50, alignSelf: 'center', justifyContent: 'space-between', alignItems: 'center' }}
                                onPress={async () => {
                                    TrackPlayer.play().then(this.setState({ isPlaying: true })).then(async () => {
                                        var dur = (await TrackPlayer.getDuration()).toString();
                                        this.setState({ trackLength: dur });
                                    });
                                }}
                            >
                                <FontAwesome5
                                    name="play"
                                    size={38}
                                    color="#000000"
                                    style={{ marginTop: 5 }}
                                />
                            </TouchableOpacity>}
                        {this.state.isPlaying && <TouchableOpacity style={{ flex: 1, height: 50, alignSelf: 'center', justifyContent: 'space-between', alignItems: 'center' }} onPress={() => TrackPlayer.pause().then(this.setState({ isPlaying: false }))}>
                            <FontAwesome5
                                name="pause"
                                size={38}
                                color="#000000"
                                style={{ marginTop: 5 }}
                            />
                        </TouchableOpacity>}
                        <TouchableOpacity style={{ flex: 1, height: 30, width: 10, alignSelf: 'center', justifyContent: 'space-between' }} onPress={() => TrackPlayer.skipToNext()}>
                            <FontAwesome5 name="forward" size={32} color="#242320" style={{ alignSelf: 'center' }} />
                        </TouchableOpacity>
                        <TouchableOpacity style={{ flex: 1, height: 30, width: 10, alignSelf: 'center', justifyContent: 'space-between', alignItems: 'center' }}>
                            <Entypo
                                name="shuffle"
                                size={30}
                                color="#000000"
                                style={{ alignItems: 'center' }}
                            />
                        </TouchableOpacity>
                    </View>

                    {/* up next section */}
                    <Surface raised style={{ width: '95%', backgroundColor: 'black', alignSelf: 'center', height: 70, borderRadius: 10, marginTop: 5 }}>
                        <Card.Title
                            style={{ backgroundColor: 'white', flex: 1, borderRadius: 10 }}
                            title={'Song Name here'}
                            titleStyle={{ margin: 25, padding: 0 }}
                            left={() =>
                                <Image
                                    style={{ width: 50, height: 50, borderRadius: 10, alignSelf: 'flex-start', alignItems: 'flex-start' }}
                                    source={require('../../assets/images/temp.jpeg')}
                                />
                            }
                            leftStyle={{ alignItems: 'flex-start', margin: -10, padding: 0 }}
                            right={() => <Badge children={'Next'} size={30} style={{ width: 70, backgroundColor: 'black', borderRadius: 5, marginRight: 10 }} />}
                        />
                    </Surface>
                </View>
            </SafeAreaView>

        );
    }
}

抱歉,代码混乱,但 cmets 有助于导航到主要部分,如 滑块和播放按钮

错误: My Error from the slider

【问题讨论】:

    标签: reactjs firebase react-native slider fetch


    【解决方案1】:

    对于那些可能需要答案的人,我使用 React Hooks 解决了这个问题。 React Native Track Player 有一个 v2 更新,其中将上述类组件转换为功能组件就可以了。它比以前给出了相当准确的结果。请参阅此处的docs。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      • 2020-09-06
      • 2020-04-24
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      相关资源
      最近更新 更多