Как показать, загружается ли файл в React native audio? - PullRequest
0 голосов
/ 08 марта 2020

Я использую Expo Audio в своем собственном приложении. При первой загрузке экрана создается впечатление, что для загрузки аудиофайла требуется пара секунд. Я хотел бы показать пользователю, загружается ли файл, когда это происходит. Я попытался использовать часть состояния isBuffering и отобразить ее в разделе рендеринга, как показано ниже:

    {this.state.isBuffering}

Но при попытке это ничего не отображалось. Как выяснить состояние загрузки файла (все еще загружается, буферизуется и т. Д. c), а затем отобразить это пользователю?

    import React, {useState, useEffect} from 'react';
    import {View, Text, StyleSheet, TouchableOpacity, Button, Linking } from 'react-native';
    import { Ionicons } from '@expo/vector-icons';
    import { Audio } from 'expo-av';

    export default class AudioplayerScreen extends React.Component {

        // Prevent the header from being shown and user from swiping backwards
        static navigationOptions = {
            headerShown: false,
            gestureEnabled: false
        }

        constructor(props){
            super(props);
            this.name = props.navigation.getParam('name');
            this.audio_file = props.navigation.getParam('audio_file');
            this.length = props.navigation.getParam('length');
            this.long_desc = props.navigation.getParam('long_desc');
            this.category = props.navigation.getParam('category');
            this.spotify_link = props.navigation.getParam('spotify_link');
            this.state = {
                isPlaying: false,
                playbackInstance: null,
                currentIndex: 0,
                volume: 1.0,
                isBuffering: false
              }
          }

          async componentDidMount() {
            try {
              await Audio.setAudioModeAsync({
                allowsRecordingIOS: false,
                interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_MIX_WITH_OTHERS,
                // interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DUCK_OTHERS,
                playsInSilentModeIOS: true,
                interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DUCK_OTHERS,
                shouldDuckAndroid: true,
                staysActiveInBackground: true,
                playThroughEarpieceAndroid: true
              })
              this.loadAudio()
            } catch (e) {
              console.log(e)
            }
          }

          async loadAudio() {
            const {currentIndex, isPlaying, volume} = this.state
            try {
              const playbackInstance = new Audio.Sound()
              const source = {
                uri: this.audio_file
              }
              const status = {
                shouldPlay: isPlaying,
                volume
              }
              playbackInstance.setOnPlaybackStatusUpdate(this.onPlaybackStatusUpdate)
              await playbackInstance.loadAsync(source, status, false)
              this.setState({playbackInstance})
              } catch (e) {
                console.log(e)
              }
          }

          onPlaybackStatusUpdate = status => {
            this.setState({
              isBuffering: status.isBuffering
            })
          }

          handlePlayPause = async () => {
            const { isPlaying, playbackInstance } = this.state
            isPlaying
              ? await playbackInstance.pauseAsync()
              : await playbackInstance.playAsync()
            this.setState({
              isPlaying: !isPlaying
            })
          }

        // Exit button
          exitScreen = async () => {
            const { isPlaying, playbackInstance } = this.state
            isPlaying
              ? await playbackInstance.pauseAsync()
              : null
            this.setState({
              isPlaying: !isPlaying
            })

            this.props.navigation.pop();
          }


          render () {
                return (
                    <View style={styles.container}>

                        <Button 
                            title="End" 
                            onPress={this.exitScreen} 
                            style={styles.endButton}
                            color="#f194ff" 
                            />

                        <Text style={styles.category}> {this.category} </Text>

                        <Text style={styles.titleOfWorkout}> {this.name} </Text>

                        <Text style={styles.lengthOfWorkout}> {this.length} minutes</Text>

                        <Text style={styles.longDescription}> {this.long_desc} </Text>

                        <View style={styles.controls}>

                            <TouchableOpacity style={styles.control} onPress={this.handlePlayPause}>
                            {this.state.isPlaying ? (
                                <Ionicons name="ios-pause" size={112} color="rgba(74,144,226,1)" />
                            ) : (
                                <Ionicons name="ios-play-circle" size={112} color="rgba(74,144,226,1)" />
                            )}
                            </TouchableOpacity>

                        </View>

                        <TouchableOpacity style={styles.control} onPress={ ()=>{ Linking.openURL( `${this.spotify_link}` )}} >
                            <Ionicons name="ios-musical-notes" style={styles.music}  ></Ionicons>
                        </TouchableOpacity>



                    </View>
                );
        }
    }

    const styles = StyleSheet.create({
        container: {
          flex: 1,
          backgroundColor: 'white',
          alignItems: 'center',
          justifyContent: 'center'
        },
        endButton: {
            borderRadius: 15,
            backgroundColor: 'grey'
        },
        category: {
            color: "rgba(74,144,226,1)",
            fontWeight: 'bold',
            fontSize: 14,
            marginTop: 50
          },
        titleOfWorkout: {
          color: "#121212",
          fontSize: 30,
          fontWeight: 'bold',
          marginTop: 50
        },
        lengthOfWorkout: {
            color: "#121212",
            opacity: 0.8,
            fontSize: 14,
            marginTop: 50
          },
        longDescription: {
            width: 283,
            color: "#121212",
            opacity: 0.8,
            marginTop: 50,
            fontSize: 14,
            top: 0
          },
          slider: {
            height: 43,
            width: 271,
            marginTop: 50
          },
        icon: {
          color: "rgba(74,144,226,1)",
          fontSize: 112,
          marginTop: 50,
          alignItems: 'center',
          justifyContent: 'center',
        },
        music: {
          color: "rgba(74,144,226,1)",
          fontSize: 45,
          marginTop: 20
        },
        control: {
            margin: 20
          },
        controls: {
            flexDirection: 'row'
          }

      });
...