javascriptreactjsreact-nativereact-native-track-player

Play audio from list of images and audio, when audio component is in focus


I have a list of image and audio as:-

postArray: [
        { "id": 1, "media_type": "image", "media_url": "https://homepages.cae.wisc.edu/~ece533/images/airplane.png", "title": "image1" },
        { "id": 2, "media_type": "audio", "media_url": "https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3", "title": "audio1" },
        { "id": 3, "media_type": "image", "media_url": "https://homepages.cae.wisc.edu/~ece533/images/airplane.png", "title": "image1" },
        { "id": 4, "media_type": "audio", "media_url": "https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3", "title": "audio1" },
    ]

and I am using react-native-track-player

I have to play if audio component is in focus. What I have tried til now:-

useEffect(() => {
    audioSetup()
}, [])

async function audioSetup() {
    await TrackPlayer.setupPlayer({});
    await TrackPlayer.updateOptions({
        stopWithApp: true,
        capabilities: [
            TrackPlayer.CAPABILITY_PLAY,
            TrackPlayer.CAPABILITY_PAUSE,
            TrackPlayer.CAPABILITY_SKIP_TO_NEXT,
            TrackPlayer.CAPABILITY_SKIP_TO_PREVIOUS,
            TrackPlayer.CAPABILITY_STOP
        ],
        compactCapabilities: [
            TrackPlayer.CAPABILITY_PLAY,
            TrackPlayer.CAPABILITY_PAUSE
        ]
    });
}

my render part of FlatList:-

 const renderPost = ({ item, index }) => {
    if (item.media_type === "image") {
        return (
            <View style={{
                marginBottom: constants.vh(16),
                marginTop: constants.vh(16),
            }}>
                <ImagePost
                    backgroundImage={item.media_url}
                    profileImage={props.auth.userRegistered.profileImage ? props.auth.userRegistered.profileImage : "https://homepages.cae.wisc.edu/~ece533/images/girl.png"}
                    firstName={props.auth.userRegistered.firstName}
                    lastName={props.auth.userRegistered.lastName}
                    likeCount={649823}
                    commentCount={45423}
                    shareCount={46312}
                    isLiked={true}
                    musicTitle={item.title}
                    description={item.description}
                />
            </View>
        )
    }
    if (item.media_type === "audio"){
        return (
            <View style={{
                marginBottom: constants.vh(16),
                marginTop: constants.vh(16),
            }}>
                <AudioPost
                    backgroundImage={item.media_url}
                    profileImage={props.auth.userRegistered.profileImage ? props.auth.userRegistered.profileImage : "https://homepages.cae.wisc.edu/~ece533/images/girl.png"}
                    firstName={props.auth.userRegistered.firstName}
                    lastName={props.auth.userRegistered.lastName}
                    likeCount={649823}
                    commentCount={45423}
                    shareCount={46312}
                    isLiked={true}
                    musicTitle={item.title}
                    playedTime={10}
                    totalTime={100}
                    description={item.description}
                />
            </View>
        )
    }

And my FlatList is as:-

const onViewableItemsChanges = async (info) => {
    await TrackPlayer.reset();
    console.log("item view able changed", info);
    if (info.changed[0].item.media_type === "audio") {
        audioSetup()
        await TrackPlayer.add({
            "id": "0",
            "url": info.changed[0].item.media_url,
            "artist": "author",
            "title": "song titile"

        });
        await TrackPlayer.play();
    }

}

                      <FlatList
                        data={state.postArray}
                        showsHorizontalScrollIndicator={false}
                        showsVerticalScrollIndicator={false}
                        renderItem={renderPost}
                         onViewableItemsChanged={onViewableItemsChanges}
                         viewabilityConfig={{ viewAreaCoveragePercentThreshold: 50 }}
                        keyExtractor={(item, index) => index.toString()}
                    />

It giving me error:- Changing onViewableItemsChanged on the fly is not supported


Solution

  • Fix by using useRef:-

    const onViewRef = React.useRef((info) => {
        TrackPlayer.reset();
        setVideoUri("")
        setVideoIndex(0)
        if (info.changed[0].item.media_type === "audio") {
            TrackPlayer.add({
                "id": "0",
                "url": info.changed[0].item.media_url,
                "artist": "author",
                "title": "song titile"
            });
            TrackPlayer.getDuration().then(totalDuration => {
                console.log("totalDuration", totalDuration);
            })
    
            TrackPlayer.play();
        }
        
    })
    const viewConfigRef = React.useRef({ viewAreaCoveragePercentThreshold: 50 })