react-native-eno-audio-stream
Version:
A player for play sound
572 lines (534 loc) • 17.4 kB
JavaScript
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;