├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── Example ├── .babelrc ├── .buckconfig ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .watchmanconfig ├── App.js ├── __tests__ │ └── App.js ├── android │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── keystores │ │ ├── BUCK │ │ └── debug.keystore.properties │ └── settings.gradle ├── app.json ├── index.js ├── ios │ ├── Example-tvOS │ │ └── Info.plist │ ├── Example-tvOSTests │ │ └── Info.plist │ ├── Example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── Example-tvOS.xcscheme │ │ │ └── Example.xcscheme │ ├── Example │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ └── default_artwork-t300x300.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── default_artwork-t300x300.png │ │ ├── Info.plist │ │ └── main.m │ └── ExampleTests │ │ ├── ExampleTests.m │ │ └── Info.plist ├── package.json └── yarn.lock ├── LICENSE ├── README.md ├── android ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── allthatseries │ │ └── RNAudioPlayer │ │ ├── AlbumArtCache.java │ │ ├── AudioPlayerService.java │ │ ├── MediaNotificationManager.java │ │ ├── Playback.java │ │ ├── PlaybackAction.java │ │ ├── RNAudioPlayerModule.java │ │ ├── RNAudioPlayerPackage.java │ │ └── utils │ │ └── BitmapHelper.java │ └── res │ ├── drawable-hdpi │ ├── ic_default_art.png │ ├── ic_launcher_white.png │ ├── ic_pause_black_36dp.png │ ├── ic_pause_white_24dp.png │ ├── ic_pause_white_48dp.png │ ├── ic_play_arrow_black_36dp.png │ ├── ic_play_arrow_white_24dp.png │ ├── ic_play_arrow_white_48dp.png │ ├── ic_skip_next_white_24dp.png │ ├── ic_skip_next_white_48dp.png │ ├── ic_skip_previous_white_24dp.png │ └── ic_skip_previous_white_48dp.png │ ├── drawable-mdpi │ ├── ic_default_art.png │ ├── ic_launcher_white.png │ ├── ic_pause_black_36dp.png │ ├── ic_pause_white_24dp.png │ ├── ic_pause_white_48dp.png │ ├── ic_play_arrow_black_36dp.png │ ├── ic_play_arrow_white_24dp.png │ ├── ic_play_arrow_white_48dp.png │ ├── ic_skip_next_white_24dp.png │ ├── ic_skip_next_white_48dp.png │ ├── ic_skip_previous_white_24dp.png │ └── ic_skip_previous_white_48dp.png │ ├── drawable-xhdpi │ ├── ic_default_art.png │ ├── ic_launcher_white.png │ ├── ic_pause_black_36dp.png │ ├── ic_pause_white_24dp.png │ ├── ic_pause_white_48dp.png │ ├── ic_play_arrow_black_36dp.png │ ├── ic_play_arrow_white_24dp.png │ ├── ic_play_arrow_white_48dp.png │ ├── ic_skip_next_white_24dp.png │ ├── ic_skip_next_white_48dp.png │ ├── ic_skip_previous_white_24dp.png │ └── ic_skip_previous_white_48dp.png │ ├── drawable-xxhdpi │ ├── ic_default_art.png │ ├── ic_launcher_white.png │ ├── ic_pause_black_36dp.png │ ├── ic_pause_white_24dp.png │ ├── ic_pause_white_48dp.png │ ├── ic_play_arrow_black_36dp.png │ ├── ic_play_arrow_white_24dp.png │ ├── ic_play_arrow_white_48dp.png │ ├── ic_skip_next_white_24dp.png │ ├── ic_skip_next_white_48dp.png │ ├── ic_skip_previous_white_24dp.png │ └── ic_skip_previous_white_48dp.png │ └── drawable-xxxhdpi │ ├── ic_default_art.png │ ├── ic_launcher_white.png │ ├── ic_pause_black_36dp.png │ ├── ic_pause_white_24dp.png │ ├── ic_pause_white_48dp.png │ ├── ic_play_arrow_black_36dp.png │ ├── ic_play_arrow_white_24dp.png │ ├── ic_play_arrow_white_48dp.png │ ├── ic_skip_next_white_24dp.png │ ├── ic_skip_next_white_48dp.png │ ├── ic_skip_previous_white_24dp.png │ └── ic_skip_previous_white_48dp.png ├── index.js ├── ios ├── RNAudioPlayer.xcodeproj │ └── project.pbxproj └── RNAudioPlayer │ ├── RNAudioPlayer.h │ └── RNAudioPlayer.m └── package.json /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb", 4 | "plugins": [ 5 | "prefer-object-spread" 6 | ], 7 | "rules": { 8 | "prefer-object-spread/prefer-object-spread": 2, 9 | "react/jsx-filename-extension": 0, 10 | "react/prefer-stateless-function": 0, 11 | "react/sort-comp": 0, 12 | "no-use-before-define": 0, 13 | "no-underscore-dangle": 0, 14 | "import/no-unresolved": [2, { "ignore": ["react"] }] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | *.moved-aside 17 | DerivedData 18 | *.hmap 19 | *.ipa 20 | *.xcuserstate 21 | project.xcworkspace 22 | 23 | # Android/IJ 24 | *.iml 25 | .idea 26 | .gradle 27 | local.properties 28 | *.hprof 29 | 30 | # node.js 31 | node_modules/ 32 | npm-debug.log 33 | 34 | # BUCK 35 | buck-out/ 36 | \.buckd/ 37 | android/app/libs 38 | android/keystores/debug.keystore -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | Example -------------------------------------------------------------------------------- /Example/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } 4 | -------------------------------------------------------------------------------- /Example/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /Example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | .*/Libraries/polyfills/.* 18 | 19 | ; Ignore metro 20 | .*/node_modules/metro/.* 21 | 22 | [include] 23 | 24 | [libs] 25 | node_modules/react-native/Libraries/react-native/react-native-interface.js 26 | node_modules/react-native/flow/ 27 | node_modules/react-native/flow-github/ 28 | 29 | [options] 30 | emoji=true 31 | 32 | module.system=haste 33 | 34 | munge_underscores=true 35 | 36 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 37 | 38 | module.file_ext=.js 39 | module.file_ext=.jsx 40 | module.file_ext=.json 41 | module.file_ext=.native.js 42 | 43 | suppress_type=$FlowIssue 44 | suppress_type=$FlowFixMe 45 | suppress_type=$FlowFixMeProps 46 | suppress_type=$FlowFixMeState 47 | 48 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 49 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 50 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 51 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 52 | 53 | [version] 54 | ^0.63.0 55 | -------------------------------------------------------------------------------- /Example/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | -------------------------------------------------------------------------------- /Example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Example/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { StyleSheet, Text, View, Button, DeviceEventEmitter, Slider } from 'react-native'; 3 | import Player from 'react-native-audio-streaming-player'; 4 | 5 | const PLAYBACK_STATE = { 6 | STATE_NONE: 0, 7 | STATE_STOPPED: 1, 8 | STATE_PAUSED: 2, 9 | STATE_PLAYING: 3, 10 | STATE_FAST_FORWARDING: 4, 11 | STATE_REWINDING: 5, 12 | STATE_BUFFERING: 6, 13 | STATE_ERROR: 7, 14 | STATE_CONNECTING: 8, 15 | STATE_SKIPPING_TO_PREVIOUS: 9, 16 | STATE_SKIPPING_TO_NEXT: 10, 17 | STATE_SKIPPING_TO_QUEUE_ITEM: 11, 18 | }; 19 | 20 | export default class Example extends Component { 21 | constructor(props) { 22 | super(props); 23 | 24 | this.state = { 25 | currentTime: 0, 26 | index: 0, 27 | playlist: null, 28 | status: 'STOPPED', 29 | }; 30 | 31 | this.dragging = false; 32 | 33 | this.onPlaybackActionChanged = this.onPlaybackActionChanged.bind(this); 34 | this.onPlaybackPositionUpdated = this.onPlaybackPositionUpdated.bind(this); 35 | this.onPlaybackStateChanged = this.onPlaybackStateChanged.bind(this); 36 | } 37 | 38 | componentWillMount() {} 39 | 40 | componentDidMount() { 41 | DeviceEventEmitter.addListener('onPlaybackPositionUpdated', this.onPlaybackPositionUpdated); 42 | DeviceEventEmitter.addListener('onPlaybackStateChanged', this.onPlaybackStateChanged); 43 | DeviceEventEmitter.addListener('onPlaybackActionChanged', this.onPlaybackActionChanged); 44 | } 45 | 46 | componentWillUnmount() { 47 | DeviceEventEmitter.removeAllListeners(); 48 | } 49 | 50 | onPlaybackPositionUpdated(event) { 51 | console.log('Current position: ' + event.currentPosition); 52 | 53 | if (this.state.status === 'PLAYING') { 54 | if (!this.dragging) { 55 | this.setState({ 56 | currentTime: parseInt(event.currentPosition), // convert milisecond to second 57 | }); 58 | } 59 | } 60 | } 61 | 62 | onPlaybackActionChanged(event) { 63 | console.log('Current Action: ' + event.action); 64 | } 65 | 66 | onPlaybackStateChanged(event) { 67 | console.log('PlaybackState: ' + event.state); 68 | this.setState({ status: event.state }); 69 | } 70 | 71 | onPlay() { 72 | const { playlist, index } = this.state; 73 | 74 | Player.play('http://pianosolo.streamguys.net/live.m3u', { 75 | title: 'Aaron', 76 | artist: 'Celine Dion', 77 | album_art_uri: 'https://unsplash.it/300/300', 78 | }); 79 | } 80 | 81 | onPause() { 82 | Player.pause(); 83 | } 84 | 85 | onStop() { 86 | this.setState({ 87 | currentTime: 0, 88 | }); 89 | Player.stop(); 90 | } 91 | 92 | onNext() { 93 | const { playlist, index } = this.state; 94 | 95 | this.setState( 96 | { 97 | currentTime: 0, 98 | index: (index + 1) % playlist.length, 99 | }, 100 | () => { 101 | this.onPlay(); 102 | }, 103 | ); 104 | } 105 | 106 | onPrev() { 107 | const { playlist, index } = this.state; 108 | 109 | this.setState( 110 | { 111 | currentTime: 0, 112 | index: index === 0 ? playlist.length - 1 : index, 113 | }, 114 | () => { 115 | this.onPlay(); 116 | }, 117 | ); 118 | } 119 | 120 | onSeekTo(pos) { 121 | this.dragging = false; 122 | Player.seekTo(pos); 123 | } 124 | 125 | render() { 126 | const { playlist, index, currentTime } = this.state; 127 | 128 | return ( 129 | 130 | 133 |