Giter VIP home page Giter VIP logo

playlist-example's Introduction

playlist-example's People

Contributors

calebnance avatar cruzach avatar dependabot[bot] avatar esamelson avatar expbot avatar gkufera avatar ide avatar kbrandwijk avatar nicknovitski avatar szymon20000 avatar terribleben avatar wodin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

playlist-example's Issues

App don't work

White screen with warning message

[06:13:58] [Unhandled promise rejection: TypeError: undefined is not an object (evaluating 'ExpoFontLoader.loadAsync')]
- node_modules/expo-font/src/Font.js:141:23 in _loadSingleFontAsync$
- node_modules/regenerator-runtime/runtime.js:62:44 in tryCatch
- ... 14 more stack frames from framework internals

Playlist stops when put into the background

Great example. Only problem is that the playlist stops when you put the app into the background. Any idea on how to get it to keep playing the current item, AND advance to the next item all while in the background?

undefined is not an object (evaluating 'sound.stopAsync') New to development if anyone could help me out that would be awesome!

i keep getting this error about sound.stopAsync is not an object but I can use it to stop playback so I don't know what the issue is or how to fix it.

import { Text, View, StyleSheet, Pressable, Alert} from 'react-native';
import Colors from '../constants/Colors';
import {Ionicons } from '@expo/vector-icons';
import { Audio } from 'expo-av';

import React, { useState, useEffect } from 'react';

const Timer = (props) => {
const [seconds, setSeconds] = useState(props.time);
const [isActive, setIsActive] = useState(false);
const [sound, setSound] = useState();

async function playSound() {
const { sound } = await Audio.Sound.createAsync(
require('../assets/mysterious_bass.wav'),

);

setSound(sound);

await sound.playAsync();

}

useEffect(() => {
return sound
? () => {
sound.unloadAsync();
}
: undefined;

}, [sound]);

useEffect(()=>{
if(seconds === 0){
playSound();

} 

},[seconds])

const toggle= async()=> {
setIsActive(!isActive);
try {
await sound.stopAsync();
} catch (error) {
console.error(error);
}

}

const reset = async () => {
setSeconds(props.time);
setIsActive(false);
try {
await sound.stopAsync();
} catch (error) {
console.error(error);
}
}

useEffect(() => {
let interval = null;

if (isActive) {
  interval = setInterval(() => {
    setSeconds(seconds => seconds - 1);
   
  }, 1000);
} else if (!isActive && seconds !== 0) {
  clearInterval(interval);
} 
return () => clearInterval(interval);

}, [isActive, seconds]);

return (




{isActive ? : <Ionicons size={59}name='play'/>}




00:{seconds}


Reset




);
};

package.json

{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.3.0",
"@fortawesome/free-regular-svg-icons": "^6.0.0-beta3",
"@fortawesome/free-solid-svg-icons": "^6.0.0",
"@fortawesome/react-fontawesome": "^0.1.17",
"@fortawesome/react-native-fontawesome": "^0.2.7",
"@react-native-community/masked-view": "^0.1.11",
"@react-navigation/bottom-tabs": "^6.2.0",
"axios": "^0.26.0",
"expo": "~44.0.0",
"expo-app-loading": "~1.3.0",
"expo-av": "~10.2.0",
"expo-linear-gradient": "~11.0.3",
"expo-status-bar": "~1.2.0",
"firebase": "^9.6.7",
"firebase-functions": "^3.18.1",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-icons": "^4.3.1",
"react-native": "0.64.3",
"react-native-elements": "^3.4.2",
"react-native-gesture-handler": "~2.1.0",
"react-native-linear-gradient": "^2.5.6",
"react-native-reanimated": "~2.3.1",
"react-native-safe-area-context": "^3.3.2",
"react-native-screens": "~3.10.1",
"react-native-svg": "^12.1.1",
"react-native-web": "0.17.1",
"react-navigation": "^4.4.4",
"react-navigation-header-buttons": "^6.3.1",
"react-navigation-material-bottom-tabs": "^2.3.5",
"react-navigation-stack": "^2.10.4",
"react-redux": "^7.2.6",
"redux": "^4.1.2",
"redux-thunk": "^2.4.1"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"typescript": "^4.5.5"
},
"private": true
}

How to run this app?

After cloning the folder, i ran the command yarn install.
when i am trying to run expo start, i am facing the following error
error Invalid regular expression: /(.\fixtures\.|node_modules[\]react[\]dist[\].|website\node_modules\.|heapCapture\bundle.js|.\tests\.)$/: Unterminated character class.

uri remote not working with query string parameter on iOS

This code not working when having parameter but works without it ?token=SOME_TOKEN

<Video
  ref={videoRef}
  source={{uri: 'https://www.something.com/video.mp4?token=SOME_TOKEN'}}
  rate={1.0}
  volume={1.0}
  isMuted={false}
  resizeMode="cover"
  shouldPlay
  isLooping
  style={{ width: '100%', height: '100%' }}
/>

Does it work with m3u8?

I need to show live streaming video in Expo react native app. I tried expo-video but it only plays mp4 videos not live stream if i'm not wrong. I don't want to eject from expo. Is there any expo library or any other way to play hls m3u8 or rtmp live streaming?

Background staysActiveInBackground argument for Audio.setAudioModeAsync(mode)

The playlist does not keep playing in the background even after changing the Audio Mode.

Audio.setAudioModeAsync({
      allowsRecordingIOS: false,
      staysActiveInBackground: true, <--- Changed this
      playsInSilentModeIOS: true,
      shouldDuckAndroid: true,
      interruptionModeAndroid: InterruptionModeAndroid.DoNotMix,
      playThroughEarpieceAndroid: false
    });

I cloned the project, changed that value and that's all I did.

Is there anything extra that needs to be done in this example to have it work in the background?

Thank you!

demo script can no longer play video

I would like to try your demo app, however the video playback feature is no longer working.

Could you kindly, update the script to EXPO 31 SKD Version?

Thanks so much!

Error on startup: Native module cannot be null

I'm getting this error on startup:

Native module cannot be null.

NativeEventEmitter
    NativeEventEmitter.js:35:16
EventEmitter
    EventEmitter.js:21:48
<unknown>
    Location.js:8:46
loadModuleImplementation
    require.js:214:12
<unknown>
    Expo.js:5
loadModuleImplementation
    require.js:214:12
<unknown>
    AppEntry.js:1
loadModuleImplementation
    require.js:214:12
guardedLoadModule
    require.js:141:45
global code
    <unknown file>:0

Player gets stuck on "... Loading ..."

Attempting to copy contents of main.js into my code and to test this out and I'm unable to play the audio or video from the playlist.

It either gets stuck on "... loading ..." when I navigate to the screen, or it loads the playlist item and then gets stuck on "...buffering..." and am unable to play play the playlist item.

Sometimes, when navigating to another playlist item all the icons gray out and it gets stuck with both "...loading..." and "...buffering..." displayed.

screen shot 2017-07-19 at 6 16 52 pm

How to load Playlist from json file on app start up

Wonderful example. Is there a way to load a json file that can be imported and fetched in at the time the user opens the app to get a fresh and updated list of streams? I would appreciate if you can give me some pointers on how to accomplish that. Thanks and great work!

Loading delay in safari browser

When it is in the web version, in safari it takes a long time to load the song (more than 10 seconds), is there a way to stream it?

onseek function

Hi , how to call a function onseek ! I am not able to use react-native-video

How to play audio file as soon as screen is loaded

Hi, is there a way to play a local bundled audio file as soon as the component is loaded or rendered?

similar to on html

So that it is played as an intro sound without any required interaction from the user.

Thanks

Should the video updates work on SDK 18?

I copied the contents of main.js into one of the screens in my app and the player gets stuck on "... loading ..." with all of the buttons grayed out. I am running SDK 18... is this not expected to be fixed in SDK 19?

import React from 'react';
import {
  Dimensions,
  Image,
  Slider,
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
} from 'react-native';
import Expo, { Asset, Audio, Font, Video } from 'expo';

class Icon {
  constructor(module, width, height) {
    this.module = module;
    this.width = width;
    this.height = height;
    Asset.fromModule(this.module).downloadAsync();
  }
}

class PlaylistItem {
  constructor(name, uri, isVideo) {
    this.name = name;
    this.uri = uri;
    this.isVideo = isVideo;
  }
}

const PLAYLIST = [
  new PlaylistItem(
    'Comfort Fit - “Sorry”',
    'https://s3.amazonaws.com/exp-us-standard/audio/playlist-example/Comfort_Fit_-_03_-_Sorry.mp3',
    false
  ),
  new PlaylistItem(
    'Big Buck Bunny',
    'http://d23dyxeqlo5psv.cloudfront.net/big_buck_bunny.mp4',
    true
  ),
  new PlaylistItem(
    'Mildred Bailey – “All Of Me”',
    'https://ia800304.us.archive.org/34/items/PaulWhitemanwithMildredBailey/PaulWhitemanwithMildredBailey-AllofMe.mp3',
    false
  ),
  new PlaylistItem(
    "Popeye - I don't scare",
    'https://ia800501.us.archive.org/11/items/popeye_i_dont_scare/popeye_i_dont_scare_512kb.mp4',
    true
  ),
  new PlaylistItem(
    'Podington Bear - “Rubber Robot”',
    'https://s3.amazonaws.com/exp-us-standard/audio/playlist-example/Podington_Bear_-_Rubber_Robot.mp3',
    false
  ),
];

const ICON_PLAY_BUTTON = new Icon(
  require('./assets/images/play_button.png'),
  34,
  51
);
const ICON_PAUSE_BUTTON = new Icon(
  require('./assets/images/pause_button.png'),
  34,
  51
);
const ICON_STOP_BUTTON = new Icon(
  require('./assets/images/stop_button.png'),
  22,
  22
);
const ICON_FORWARD_BUTTON = new Icon(
  require('./assets/images/forward_button.png'),
  33,
  25
);
const ICON_BACK_BUTTON = new Icon(
  require('./assets/images/back_button.png'),
  33,
  25
);

const ICON_LOOP_ALL_BUTTON = new Icon(
  require('./assets/images/loop_all_button.png'),
  77,
  35
);
const ICON_LOOP_ONE_BUTTON = new Icon(
  require('./assets/images/loop_one_button.png'),
  77,
  35
);

const ICON_MUTED_BUTTON = new Icon(
  require('./assets/images/muted_button.png'),
  67,
  58
);
const ICON_UNMUTED_BUTTON = new Icon(
  require('./assets/images/unmuted_button.png'),
  67,
  58
);

const ICON_TRACK_1 = new Icon(require('./assets/images/track_1.png'), 166, 5);
const ICON_THUMB_1 = new Icon(require('./assets/images/thumb_1.png'), 18, 19);
const ICON_THUMB_2 = new Icon(require('./assets/images/thumb_2.png'), 15, 19);

const LOOPING_TYPE_ALL = 0;
const LOOPING_TYPE_ONE = 1;
const LOOPING_TYPE_ICONS = { 0: ICON_LOOP_ALL_BUTTON, 1: ICON_LOOP_ONE_BUTTON };

const { width: DEVICE_WIDTH, height: DEVICE_HEIGHT } = Dimensions.get('window');
const BACKGROUND_COLOR = '#FFF8ED';
const DISABLED_OPACITY = 0.5;
const FONT_SIZE = 14;
const LOADING_STRING = '... loading ...';
const BUFFERING_STRING = '...buffering...';
const RATE_SCALE = 3.0;
const VIDEO_CONTAINER_HEIGHT = DEVICE_HEIGHT * 2.0 / 5.0 - FONT_SIZE * 2;

class MediaPlayer extends React.Component {
  constructor(props) {
    super(props);
    this.index = 0;
    this.isSeeking = false;
    this.shouldPlayAtEndOfSeek = false;
    this.playbackInstance = null;
    this.state = {
      showVideo: false,
      playbackInstanceName: LOADING_STRING,
      loopingType: LOOPING_TYPE_ALL,
      muted: false,
      playbackInstancePosition: null,
      playbackInstanceDuration: null,
      shouldPlay: false,
      isPlaying: false,
      isBuffering: false,
      isLoading: true,
      fontLoaded: false,
      shouldCorrectPitch: true,
      volume: 1.0,
      rate: 1.0,
      videoWidth: DEVICE_WIDTH,
      videoHeight: VIDEO_CONTAINER_HEIGHT,
      poster: false,
      useNativeControls: false,
      fullscreen: false,
    };
  }

  componentDidMount() {
    Audio.setAudioModeAsync({
      allowsRecordingIOS: false,
      interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
      playsInSilentModeIOS: true,
      shouldDuckAndroid: true,
      interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
    });
    (async () => {
      await Font.loadAsync({
        'cutive-mono-regular': require('./assets/fonts/CutiveMono-Regular.ttf'),
      });
      this.setState({ fontLoaded: true });
    })();
  }

  async _loadNewPlaybackInstance(playing) {
    if (this.playbackInstance != null) {
      await this.playbackInstance.unloadAsync();
      this.playbackInstance.setCallback(null);
      this.playbackInstance = null;
    }

    const source = { uri: PLAYLIST[this.index].uri };
    const initialStatus = {
      shouldPlay: playing,
      rate: this.state.rate,
      shouldCorrectPitch: this.state.shouldCorrectPitch,
      volume: this.state.volume,
      isMuted: this.state.muted,
      isLooping: this.state.loopingType === LOOPING_TYPE_ONE,
    };

    if (PLAYLIST[this.index].isVideo) {
      this._video.setCallback(this._callback);
      await this._video.loadAsync(source, initialStatus);
      this.playbackInstance = this._video;
      const status = await this._video.getStatusAsync();
    } else {
      const { sound, status } = await Audio.Sound.create(
        source,
        initialStatus,
        this._callback
      );
      this.playbackInstance = sound;
    }

    this._updateScreenForLoading(false);
  }

  _mountVideo = component => {
    this._video = component;
    this._loadNewPlaybackInstance(false);
  };

  _updateScreenForLoading(isLoading) {
    if (isLoading) {
      this.setState({
        showVideo: false,
        isPlaying: false,
        playbackInstanceName: LOADING_STRING,
        playbackInstanceDuration: null,
        playbackInstancePosition: null,
        isLoading: true,
      });
    } else {
      this.setState({
        playbackInstanceName: PLAYLIST[this.index].name,
        showVideo: PLAYLIST[this.index].isVideo,
        isLoading: false,
      });
    }
  }

  _callback = status => {
    if (status.isLoaded) {
      this.setState({
        playbackInstancePosition: status.positionMillis,
        playbackInstanceDuration: status.durationMillis,
        shouldPlay: status.shouldPlay,
        isPlaying: status.isPlaying,
        isBuffering: status.isBuffering,
        rate: status.rate,
        muted: status.isMuted,
        volume: status.volume,
        loopingType: status.isLooping ? LOOPING_TYPE_ONE : LOOPING_TYPE_ALL,
        shouldCorrectPitch: status.shouldCorrectPitch,
      });
      if (status.didJustFinish && !status.isLooping) {
        this._advanceIndex(true);
        this._updatePlaybackInstanceForIndex(true);
      }
    } else {
      if (status.error) {
        console.log(`FATAL PLAYER ERROR: ${status.error}`);
      }
    }
  };

  _onLoadStart = () => {
    console.log(`ON LOAD START`);
  };

  _onLoad = status => {
    console.log(`ON LOAD : ${JSON.stringify(status)}`);
  };

  _onError = error => {
    console.log(`ON ERROR : ${error}`);
  };

  _onReadyForDisplay = event => {
    const widestHeight =
      DEVICE_WIDTH * event.naturalSize.height / event.naturalSize.width;
    if (widestHeight > VIDEO_CONTAINER_HEIGHT) {
      this.setState({
        videoWidth:
          VIDEO_CONTAINER_HEIGHT *
            event.naturalSize.width /
            event.naturalSize.height,
        videoHeight: VIDEO_CONTAINER_HEIGHT,
      });
    } else {
      this.setState({
        videoWidth: DEVICE_WIDTH,
        videoHeight:
          DEVICE_WIDTH * event.naturalSize.height / event.naturalSize.width,
      });
    }
  };

  _onFullscreenUpdate = event => {
    console.log(
      `FULLSCREEN UPDATE : ${JSON.stringify(event.fullscreenUpdate)}`
    );
  };

  _advanceIndex(forward) {
    this.index =
      (this.index + (forward ? 1 : PLAYLIST.length - 1)) % PLAYLIST.length;
  }

  async _updatePlaybackInstanceForIndex(playing) {
    this._updateScreenForLoading(true);

    this.setState({
      videoWidth: DEVICE_WIDTH,
      videoHeight: VIDEO_CONTAINER_HEIGHT,
    });

    this._loadNewPlaybackInstance(playing);
  }

  _onPlayPausePressed = () => {
    if (this.playbackInstance != null) {
      if (this.state.isPlaying) {
        this.playbackInstance.pauseAsync();
      } else {
        this.playbackInstance.playAsync();
      }
    }
  };

  _onStopPressed = () => {
    if (this.playbackInstance != null) {
      this.playbackInstance.stopAsync();
    }
  };

  _onForwardPressed = () => {
    if (this.playbackInstance != null) {
      this._advanceIndex(true);
      this._updatePlaybackInstanceForIndex(this.state.shouldPlay);
    }
  };

  _onBackPressed = () => {
    if (this.playbackInstance != null) {
      this._advanceIndex(false);
      this._updatePlaybackInstanceForIndex(this.state.shouldPlay);
    }
  };

  _onMutePressed = () => {
    if (this.playbackInstance != null) {
      this.playbackInstance.setIsMutedAsync(!this.state.muted);
    }
  };

  _onLoopPressed = () => {
    if (this.playbackInstance != null) {
      this.playbackInstance.setIsLoopingAsync(
        this.state.loopingType !== LOOPING_TYPE_ONE
      );
    }
  };

  _onVolumeSliderValueChange = value => {
    if (this.playbackInstance != null) {
      this.playbackInstance.setVolumeAsync(value);
    }
  };

  _trySetRate = async (rate, shouldCorrectPitch) => {
    if (this.playbackInstance != null) {
      try {
        await this.playbackInstance.setRateAsync(rate, shouldCorrectPitch);
      } catch (error) {
        // Rate changing could not be performed, possibly because the client's Android API is too old.
      }
    }
  };

  _onRateSliderSlidingComplete = async value => {
    this._trySetRate(value * RATE_SCALE, this.state.shouldCorrectPitch);
  };

  _onPitchCorrectionPressed = async value => {
    this._trySetRate(this.state.rate, !this.state.shouldCorrectPitch);
  };

  _onSeekSliderValueChange = value => {
    if (this.playbackInstance != null && !this.isSeeking) {
      this.isSeeking = true;
      this.shouldPlayAtEndOfSeek = this.state.shouldPlay;
      this.playbackInstance.pauseAsync();
    }
  };

  _onSeekSliderSlidingComplete = async value => {
    if (this.playbackInstance != null) {
      this.isSeeking = false;
      const seekPosition = value * this.state.playbackInstanceDuration;
      if (this.shouldPlayAtEndOfSeek) {
        this.playbackInstance.playFromPositionAsync(seekPosition);
      } else {
        this.playbackInstance.setPositionAsync(seekPosition);
      }
    }
  };

  _getSeekSliderPosition() {
    if (
      this.playbackInstance != null &&
      this.state.playbackInstancePosition != null &&
      this.state.playbackInstanceDuration != null
    ) {
      return (
        this.state.playbackInstancePosition /
        this.state.playbackInstanceDuration
      );
    }
    return 0;
  }

  _getMMSSFromMillis(millis) {
    const totalSeconds = millis / 1000;
    const seconds = Math.floor(totalSeconds % 60);
    const minutes = Math.floor(totalSeconds / 60);

    const padWithZero = number => {
      const string = number.toString();
      if (number < 10) {
        return '0' + string;
      }
      return string;
    };
    return padWithZero(minutes) + ':' + padWithZero(seconds);
  }

  _getTimestamp() {
    if (
      this.playbackInstance != null &&
      this.state.playbackInstancePosition != null &&
      this.state.playbackInstanceDuration != null
    ) {
      return `${this._getMMSSFromMillis(
        this.state.playbackInstancePosition
      )} / ${this._getMMSSFromMillis(this.state.playbackInstanceDuration)}`;
    }
    return '';
  }

  _onPosterPressed = () => {
    this.setState({ poster: !this.state.poster });
  };

  _onUseNativeControlsPressed = () => {
    this.setState({ useNativeControls: !this.state.useNativeControls });
  };

  _onFullscreenPressed = () => {
    try {
      this._video.presentIOSFullscreenPlayer();
    } catch (error) {
      console.log(error.toString());
    }
  };

  render() {
    return !this.state.fontLoaded
      ? <View style={styles.emptyContainer} />
      : <View style={styles.container}>
          <View />
          <View style={styles.nameContainer}>
            <Text
              style={[styles.text, { ...Font.style('cutive-mono-regular') }]}>
              {this.state.playbackInstanceName}
            </Text>
          </View>
          <View style={styles.space} />
          <View style={styles.videoContainer}>
            <Video
              ref={this._mountVideo}
              style={[
                styles.video,
                {
                  opacity: this.state.showVideo ? 1.0 : 0.0,
                  width: this.state.videoWidth,
                  height: this.state.videoHeight,
                },
              ]}
              resizeMode={Video.RESIZE_MODE_CONTAIN}
              callback={this._callback}
              onLoadStart={this._onLoadStart}
              onLoad={this._onLoad}
              onError={this._onError}
              onFullscreenUpdate={this._onFullscreenUpdate}
              onReadyForDisplay={this._onReadyForDisplay}
              useNativeControls={this.state.useNativeControls}
            />
          </View>
          <View
            style={[
              styles.playbackContainer,
              {
                opacity: this.state.isLoading ? DISABLED_OPACITY : 1.0,
              },
            ]}>
            <Slider
              style={styles.playbackSlider}
              trackImage={ICON_TRACK_1.module}
              thumbImage={ICON_THUMB_1.module}
              value={this._getSeekSliderPosition()}
              onValueChange={this._onSeekSliderValueChange}
              onSlidingComplete={this._onSeekSliderSlidingComplete}
              disabled={this.state.isLoading}
            />
            <View style={styles.timestampRow}>
              <Text
                style={[
                  styles.text,
                  styles.buffering,
                  { ...Font.style('cutive-mono-regular') },
                ]}>
                {this.state.isBuffering ? BUFFERING_STRING : ''}
              </Text>
              <Text
                style={[
                  styles.text,
                  styles.timestamp,
                  { ...Font.style('cutive-mono-regular') },
                ]}>
                {this._getTimestamp()}
              </Text>
            </View>
          </View>
          <View
            style={[
              styles.buttonsContainerBase,
              styles.buttonsContainerTopRow,
              {
                opacity: this.state.isLoading ? DISABLED_OPACITY : 1.0,
              },
            ]}>
            <TouchableHighlight
              underlayColor={BACKGROUND_COLOR}
              style={styles.wrapper}
              onPress={this._onBackPressed}
              disabled={this.state.isLoading}>
              <Image style={styles.button} source={ICON_BACK_BUTTON.module} />
            </TouchableHighlight>
            <TouchableHighlight
              underlayColor={BACKGROUND_COLOR}
              style={styles.wrapper}
              onPress={this._onPlayPausePressed}
              disabled={this.state.isLoading}>
              <Image
                style={styles.button}
                source={
                  this.state.isPlaying
                    ? ICON_PAUSE_BUTTON.module
                    : ICON_PLAY_BUTTON.module
                }
              />
            </TouchableHighlight>
            <TouchableHighlight
              underlayColor={BACKGROUND_COLOR}
              style={styles.wrapper}
              onPress={this._onStopPressed}
              disabled={this.state.isLoading}>
              <Image style={styles.button} source={ICON_STOP_BUTTON.module} />
            </TouchableHighlight>
            <TouchableHighlight
              underlayColor={BACKGROUND_COLOR}
              style={styles.wrapper}
              onPress={this._onForwardPressed}
              disabled={this.state.isLoading}>
              <Image
                style={styles.button}
                source={ICON_FORWARD_BUTTON.module}
              />
            </TouchableHighlight>
          </View>
          <View
            style={[
              styles.buttonsContainerBase,
              styles.buttonsContainerMiddleRow,
            ]}>
            <View style={styles.volumeContainer}>
              <TouchableHighlight
                underlayColor={BACKGROUND_COLOR}
                style={styles.wrapper}
                onPress={this._onMutePressed}>
                <Image
                  style={styles.button}
                  source={
                    this.state.muted
                      ? ICON_MUTED_BUTTON.module
                      : ICON_UNMUTED_BUTTON.module
                  }
                />
              </TouchableHighlight>
              <Slider
                style={styles.volumeSlider}
                trackImage={ICON_TRACK_1.module}
                thumbImage={ICON_THUMB_2.module}
                value={1}
                onValueChange={this._onVolumeSliderValueChange}
              />
            </View>
            <TouchableHighlight
              underlayColor={BACKGROUND_COLOR}
              style={styles.wrapper}
              onPress={this._onLoopPressed}>
              <Image
                style={styles.button}
                source={LOOPING_TYPE_ICONS[this.state.loopingType].module}
              />
            </TouchableHighlight>
          </View>
          <View
            style={[
              styles.buttonsContainerBase,
              styles.buttonsContainerBottomRow,
            ]}>
            <TouchableHighlight
              underlayColor={BACKGROUND_COLOR}
              style={styles.wrapper}
              onPress={() =>
                this._trySetRate(1.0, this.state.shouldCorrectPitch)}>
              <View style={styles.button}>
                <Text
                  style={[
                    styles.text,
                    { ...Font.style('cutive-mono-regular') },
                  ]}>
                  Rate:
                </Text>
              </View>
            </TouchableHighlight>
            <Slider
              style={styles.rateSlider}
              trackImage={ICON_TRACK_1.module}
              thumbImage={ICON_THUMB_1.module}
              value={this.state.rate / RATE_SCALE}
              onSlidingComplete={this._onRateSliderSlidingComplete}
            />
            <TouchableHighlight
              underlayColor={BACKGROUND_COLOR}
              style={styles.wrapper}
              onPress={this._onPitchCorrectionPressed}>
              <View style={styles.button}>
                <Text
                  style={[
                    styles.text,
                    { ...Font.style('cutive-mono-regular') },
                  ]}>
                  PC: {this.state.shouldCorrectPitch ? 'yes' : 'no'}
                </Text>
              </View>
            </TouchableHighlight>
          </View>
          <View />
          {this.state.showVideo
            ? <View>
                <View
                  style={[
                    styles.buttonsContainerBase,
                    styles.buttonsContainerTextRow,
                  ]}>
                  <View />
                  <TouchableHighlight
                    underlayColor={BACKGROUND_COLOR}
                    style={styles.wrapper}
                    onPress={this._onPosterPressed}>
                    <View style={styles.button}>
                      <Text
                        style={[
                          styles.text,
                          { ...Font.style('cutive-mono-regular') },
                        ]}>
                        Poster: {this.state.poster ? 'yes' : 'no'}
                      </Text>
                    </View>
                  </TouchableHighlight>
                  <View />
                  <TouchableHighlight
                    underlayColor={BACKGROUND_COLOR}
                    style={styles.wrapper}
                    onPress={this._onFullscreenPressed}>
                    <View style={styles.button}>
                      <Text
                        style={[
                          styles.text,
                          { ...Font.style('cutive-mono-regular') },
                        ]}>
                        Fullscreen
                      </Text>
                    </View>
                  </TouchableHighlight>
                  <View />
                </View>
                <View style={styles.space} />
                <View
                  style={[
                    styles.buttonsContainerBase,
                    styles.buttonsContainerTextRow,
                  ]}>
                  <View />
                  <TouchableHighlight
                    underlayColor={BACKGROUND_COLOR}
                    style={styles.wrapper}
                    onPress={this._onUseNativeControlsPressed}>
                    <View style={styles.button}>
                      <Text
                        style={[
                          styles.text,
                          { ...Font.style('cutive-mono-regular') },
                        ]}>
                        Native Controls:
                        {' '}
                        {this.state.useNativeControls ? 'yes' : 'no'}
                      </Text>
                    </View>
                  </TouchableHighlight>
                  <View />
                </View>
              </View>
            : null}
        </View>;
  }
}

const styles = StyleSheet.create({
  emptyContainer: {
    alignSelf: 'stretch',
    backgroundColor: BACKGROUND_COLOR,
  },
  container: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between',
    alignItems: 'center',
    alignSelf: 'stretch',
    backgroundColor: BACKGROUND_COLOR,
  },
  wrapper: {},
  nameContainer: {
    height: FONT_SIZE,
  },
  space: {
    height: FONT_SIZE,
  },
  videoContainer: {
    height: VIDEO_CONTAINER_HEIGHT,
  },
  video: {
    maxWidth: DEVICE_WIDTH,
  },
  playbackContainer: {
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'space-between',
    alignItems: 'center',
    alignSelf: 'stretch',
    minHeight: ICON_THUMB_1.height * 2.0,
    maxHeight: ICON_THUMB_1.height * 2.0,
  },
  playbackSlider: {
    alignSelf: 'stretch',
  },
  timestampRow: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    alignSelf: 'stretch',
    minHeight: FONT_SIZE,
  },
  text: {
    fontSize: FONT_SIZE,
    minHeight: FONT_SIZE,
  },
  buffering: {
    textAlign: 'left',
    paddingLeft: 20,
  },
  timestamp: {
    textAlign: 'right',
    paddingRight: 20,
  },
  button: {
    backgroundColor: BACKGROUND_COLOR,
  },
  buttonsContainerBase: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
  },
  buttonsContainerTopRow: {
    maxHeight: ICON_PLAY_BUTTON.height,
    minWidth: DEVICE_WIDTH / 2.0,
    maxWidth: DEVICE_WIDTH / 2.0,
  },
  buttonsContainerMiddleRow: {
    maxHeight: ICON_MUTED_BUTTON.height,
    alignSelf: 'stretch',
    paddingRight: 20,
  },
  volumeContainer: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    minWidth: DEVICE_WIDTH / 2.0,
    maxWidth: DEVICE_WIDTH / 2.0,
  },
  volumeSlider: {
    width: DEVICE_WIDTH / 2.0 - ICON_MUTED_BUTTON.width,
  },
  buttonsContainerBottomRow: {
    maxHeight: ICON_THUMB_1.height,
    alignSelf: 'stretch',
    paddingRight: 20,
    paddingLeft: 20,
  },
  rateSlider: {
    width: DEVICE_WIDTH / 2.0,
  },
  buttonsContainerTextRow: {
    maxHeight: FONT_SIZE,
    alignItems: 'center',
    paddingRight: 20,
    paddingLeft: 20,
    minWidth: DEVICE_WIDTH,
    maxWidth: DEVICE_WIDTH,
  },
});

export default MediaPlayer

screen shot 2017-07-19 at 5 47 41 pm

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.