UNPKG

react-native-eno-audio-stream

Version:

A player for play sound

572 lines (534 loc) 17.4 kB
import React, { Component } from "react"; import { Animated, Easing, Dimensions, Image, ImageBackground, Platform, Text, TouchableOpacity, View } from "react-native"; import { Button } from "native-base"; import PropTypes from "prop-types"; import * as Animatable from "react-native-animatable"; import DeviceInfo from "react-native-device-info"; import Slider from "react-native-slider"; import Sound from "react-native-sound"; import SystemSetting from "react-native-system-setting"; import styles from "./styles.js"; const { width, height } = Dimensions.get("window"); const isTablet = DeviceInfo.isTablet(); class AudioStream extends Component { constructor(props) { super(props); Sound.setCategory("Playback"); this.fadeIn = { 0: { opacity: 0, scale: 0 }, 0.5: { opacity: 1, scale: 0.3 }, 1: { opacity: 1, scale: 1 } }; this.RotateValueHolder = new Animated.Value(0); this.RotateData = this.RotateValueHolder.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] }); // const { currentTime, duration, currentAudio } = this.state; this.state = { //data count: 0, duration: "", fullScreen: false, isPlay: false, isVideo: false, title: "", thumbnail: "", track: null, volume: 0.5, //style backgroundColor: "transparent", iconPlay: require("../../assets/img/play.png"), iconPause: require("../../assets/img/pause.png"), iconArrowUp: require("../../assets/img/icon_arrow_up.png"), subTitleColor: "#FFF", titleColor: "#50E3C2" }; this.sound = null; } componentWillMount() { if (this.props.track != null) { this.setState({ track: this.props.track }); } if (this.props.volume != null) { this.setState({ volume: this.props.volume }); } if (this.props.titleColor != null) { this.setState({ titleColor: this.props.titleColor }); } if (this.props.iconPlay) { this.setState({ iconPlay: this.props.iconPlay }); } if (this.props.iconPause) { this.setState({ iconPause: this.props.iconPause }); } if (this.state.backgroundColor) { this.setState({ backgroundColor: this.props.backgroundColor }); } } componentDidMount() { SystemSetting.getVolume().then(volume => { this.setState({ volume: volume }); }); SystemSetting.setVolume(this.state.volume); // listen the volume changing if you need const volumeListener = SystemSetting.addVolumeListener(data => { this.setState({ volume: data.value }); }); } componentWillUnmount() {} stopPlaying() { this.setState({ isPlay: false }); } componentWillReceiveProps(nextProps) { if (nextProps.stopPlaying) { if (nextProps.stopPlaying) { this.stopPlaying(); } } } play() { this.startImageRotateFunction(); if (this.state.track == 0) { return; } this.sound = new Sound(this.state.track.url, null, error => { if (error) { console.log("error", error); return; } else { this.sound.setVolume(this.state.volume); this.sound.play(); } }); } pause() { this.stopImageRotateFunction(); if (this.sound != null) { this.sound.pause(); } } startImageRotateFunction() { if (this.state.count == 0) { if (this.RotateValueHolder._value == 0) { this.RotateValueHolder.setValue(0); } else { this.RotateValueHolder.setValue(this.RotateValueHolder._value); } Animated.timing(this.RotateValueHolder, { toValue: this.RotateValueHolder._value == 0 ? 1 : this.RotateValueHolder._value + 1, duration: 6000, easing: Easing.linear }).start(o => { if (o.finished == true) { this.setState({ count: 0 }, () => { if (this.RotateValueHolder._value == 0) { this.RotateValueHolder.setValue(0); } else { this.RotateValueHolder.setValue(this.RotateValueHolder._value); } }); } if (this.state.isPlayStreaming == false && o.finished == true) { // this.setState({count:0}) this.StartImageRotateFunction(); } }); } } stopImageRotateFunction() { this.RotateValueHolder.setValue(this.RotateValueHolder._value); this.RotateValueHolder.stopAnimation(); } stop() { if (sound != null) { sound.release(); } } handlePlayBackPress = () => { if (!this.state.isPlay) { this.play(); } else { this.pause(); } this.setState({ isPlay: !this.state.isPlay }); }; renderAnimateArtist() { return ( <View style={{ alignItems: "center", justifyContent: "center" }}> <Animated.Image style={[ styles.thumbnailResizeCircle, { transform: [{ rotate: this.RotateData }] } ]} source={require("../../assets/img/circle_gradient_big.png")} /> {this.state.track == null || this.state.track.artist ? ( <Animated.Image style={[ styles.thumbnailResize, { transform: [{ rotate: this.RotateData }] } ]} source={require("../../assets/img/pic_default_dj.png")} /> ) : ( <Animated.Image style={[ styles.thumbnailResize, { transform: [{ rotate: this.RotateData }] } ]} source={{ uri: this.state.track.artist }} /> )} </View> ); } renderFullScreenPlayer() { return ( <View style={styles.radioContainer}> <ImageBackground source={require("../../assets/img/bg.png")} style={styles.backgroundImage} > <View style={styles.container}> {Platform.OS == "android" ? ( <Button transparent={true} hitSlop={{ top: 0, bottom: 80, left: 50, right: 500 }} style={styles.buttonLeft} onPress={() => { this.setState({ fullScreen: !this.state.fullScreen }); }} > <Image source={require("../../assets/img/icon_arrow_down.png")} /> </Button> ) : ( <Button transparent={true} hitSlop={{ top: 0, bottom: 80, left: 50, right: 500 }} style={[styles.buttonLeft, styles.buttonLeftExtra]} onPress={() => { this.setState({ fullScreen: !this.state.fullScreen }); }} > <Image source={require("../../assets/img/icon_arrow_down.png")} /> </Button> )} <View style={styles.buttonLive}> {/* <Image source={require("../../assets/img/icon_live.png")} /> */} </View> {this.state.isVideo == false ? ( <View style={this.props.thumbnailSize}> <Animatable.View style={styles.flex} animation={this.fadeIn} duration={800} > <View style={styles.center}> <Animated.Image style={[ this.props.thumbnailSizeCircle, { transform: [{ rotate: this.RotateData }] } ]} source={require("../../assets/img/circle_gradient_big.png")} /> {this.state.track.thumbnail == null || this.state.track.thumbnail == "" ? ( <Animated.Image style={[ this.props.thumbnailSizeDJ, styles.thumnnailInside, { transform: [{ rotate: this.RotateData }] } ]} source={require("../../assets/img/pic_default_dj.png")} /> ) : ( <Animated.Image style={[ this.props.thumbnailSizeDJ, styles.thumnnailInside, { transform: [{ rotate: this.RotateData }] } ]} source={{ uri: this.state.track.thumbnail }} /> )} </View> </Animatable.View> </View> ) : this.state.isVideo == true ? ( <View style={styles.videoContent}> <Animatable.View style={{ flex: 1, alignItems: "center" }} animation="zoomIn" duration={500} > {this.renderVideo()} </Animatable.View> </View> ) : ( <View /> )} <View style={styles.detailContainer}> <Text style={[ this.props.titleStyle, { color: this.state.titleColor } ]} > {this.state.track.title ? this.state.track.title : ""} </Text> {/* {this.props.otherInfo.programStart == "unknown" ? ( <Text style={styles.contentStyle}>unknown</Text> ) : ( */} <Text style={[ styles.contentStyle, { color: this.state.subTitleColor } ]} > {/* {moment(this.props.otherInfo.programStart, "HH:mm:ss").format( "HH:mm" ) + "-" + moment(this.props.otherInfo.programEnd, "HH:mm:ss").format( "HH:mm" )} */} {this.state.track.artist ? this.state.track.artist : ""} </Text> {/* )} */} </View> <View style={[styles.buttonsContainer, styles.buttonsStyle]}> {this.renderPlayerIcon()} </View> <View style={styles.playbackContainer}> <Image source={require("../../assets/img/icon_volumn.png")} /> <Slider value={this.state.volume} style={styles.playbackBar} thumbStyle={styles.thumbStyle} thumbTintColor="#FFFFFF" maximumTrackTintColor="#CDCDD2" minimumTrackTintColor="#0CA79C" onSlidingComplete={data => { if (this.state.isPlayStreaming == false) { SystemSetting.setVolume(data); this.setState({ volume: data, count: 1 }); } else { SystemSetting.setVolume(data); this.setState({ volume: data, count: 0 }); } }} /> <Image source={require("../../assets/img/icon_volumn_up.png")} /> </View> </View> </ImageBackground> </View> ); } renderPlayerIcon() { // const { isPlay } = this.state; if (this.state.isPlay == false) { return ( <TouchableOpacity onPress={this.handlePlayBackPress}> <Image source={this.state.iconPlay} style={[styles.playButton]} /> </TouchableOpacity> ); } else { return ( <TouchableOpacity onPress={ this.handlePlayBackPress // let option_radio = { // page: Actions.currentScene, // type: 2 // }; // this.props.onChangeStyleRadio(option_radio); // SystemSetting.getVolume().then(volume => { // this.props.onChangeStatus(true, volume); // }); // Actions.refresh({ // action: { // from: '/player', // to: '/player/play', // type: 'hideHeader', // volumnSteam: this.state.volumn, // refresh: Math.random() // } // }) } > <Image source={this.state.iconPause} style={[styles.playButton]} /> </TouchableOpacity> ); } } renderPlayerIconResize() { if (!this.state.isPlay) { return ( <TouchableOpacity onPress={this.handlePlayBackPress}> {this.state.iconPlay ? ( <Image source={this.state.iconPlay} style={styles.playButtonResize} /> ) : ( <Image source={require("../../assets/img/play.png")} style={styles.playButtonResize} /> )} </TouchableOpacity> ); } else { return ( <TouchableOpacity onPress={this.handlePlayBackPress}> {this.state.iconPause ? ( <Image source={this.state.iconPause} style={styles.playButtonResize} /> ) : ( <Image source={require("../../assets/img/pause.png")} style={styles.playButtonResize} /> )} </TouchableOpacity> ); } } renderMiniPlayer() { return ( <View style={[styles.defaultPlayer, { backgroundColor: "transparent" }]}> <TouchableOpacity activeOpacity={0.8} onPress={() => { this.setState({ fullScreen: true }); }} > <View style={styles.playerResize}> <View style={styles.detailLeft}> <Image source={this.state.iconArrowUp} /> {this.renderAnimateArtist()} </View> <View style={styles.detailCenter}> <Text style={[ styles.titleStyleResize, { color: this.state.titleColor } ]} > {this.state.track.title ? this.state.track.title : ""} </Text> <View style={styles.detailCenterSub}> <Text numberOfLines={1} style={[ styles.contentStyle, { color: this.state.subTitleColor } ]} > {/* {moment(this.props.otherInfo.programStart, "HH:mm:ss").format( "HH:mm" ) + "-" + moment(this.props.otherInfo.programEnd, "HH:mm:ss").format( "HH:mm" )} */} {this.state.track.artist ? this.state.track.artist : ""} </Text> <TouchableOpacity activeOpacity={0.8} hitSlop={{ top: 20, bottom: 20, left: 50, right: 50 }} style={styles.buttonLiveResize} > <Image // source={require("../../../src/images/icon_live.png")} /> </TouchableOpacity> </View> </View> <View style={styles.center}>{this.renderPlayerIconResize()}</View> </View> </TouchableOpacity> </View> ); } render() { if (this.state.fullScreen) { return this.renderFullScreenPlayer(); } else { return this.renderMiniPlayer(); } } } AudioStream.propTypes = { playlist: PropTypes.array }; AudioStream.defaultProps = { playlist: [], thumbnailSize: { width: isTablet == true ? 170 * 2 : 170, height: isTablet == true ? 170 * 2 : 170, borderRadius: isTablet == true ? (170 * 2) / 2 : 170 / 2 }, thumbnailSizeDJ: { width: isTablet == true ? 160 * 2 : 160, height: isTablet == true ? 160 * 2 : 160, borderRadius: isTablet == true ? (160 * 2) / 2 : 160 / 2 }, thumbnailSizeCircle: { width: isTablet == true ? 170 * 2 : 170, height: isTablet == true ? 170 * 2 : 170, borderRadius: isTablet == true ? (170 * 2) / 2 : 170 / 2, position: "relative" } }; export default AudioStream;