Git Product home page Git Product logo

lijinke666 / react-music-player Goto Github PK

View Code? Open in Web Editor NEW
678.0 14.0 197.0 17.12 MB

[Stop the maintenance] :musical_note: Maybe the best beautiful HTML5 responsive player component for react :)

Home Page: https://lijinke666.github.io/react-music-player/

License: MIT License

JavaScript 86.65% HTML 0.12% Less 13.14% Shell 0.09%
react component html5 music player audio audio-player react-player react-music react-music-player

react-music-player's Introduction

logo

react-jinke-music-player

🎵 Maybe the best beautiful HTML5 responsive player component for react : )

npm npm npm version Language grade: JavaScript npm bundle size semantic release visitor

中文文档

📦 Installation

using yarn :

yarn add react-jinke-music-player

using npm :

npm install react-jinke-music-player --save

🖼️ Screenshots

mini mode

mini mode

Light Theme

light theme

Dark Theme

dark theme

mobile

mobile

✨ Feature list

👀 Example

live example :

local example : http://localhost:8081/

Source Code

📝 Usage

import React from 'react'
import ReactDOM from 'react-dom'
import ReactJkMusicPlayer from 'react-jinke-music-player'
import 'react-jinke-music-player/assets/index.css'

ReactDOM.render(
  <ReactJkMusicPlayer {...options} />,
  document.getElementById('root'),
)

📋 API

Name Type Default Description
className string - Additional CSS class for the root DOM node
audioLists AudioListProps[] - Detail
theme light | dark | auto dark color of the music player theme dark, light, auto (follow system)
locale zh_CN | en_US | CustomLocale en_US Detail
icon Customize player icon - Customize player icon
defaultPosition object {top:0,left:0} audio controller initial position with left,top,right,and bottom
playModeShowTime number 600 play mode toggle show time (ms)
bounds object,number body specifies movement boundaries. Accepted values: parent restricts movement within the node's offsetParent (nearest node with position relative or absolute), or a selector, restricts movement within the targeted node An object with left, top, right, and bottom properties. These indicate how far in each direction the draggable can be moved.
preload boolean,string false Whether to load audio immediately after the page loads. can be set to `auto
remember boolean false The next time you access the player, do you keep the last state
glassBg boolean false Whether the player's background displays frosted glass effect
remove boolean true The Audio Can be deleted
defaultPlayIndex number 0 Default play index of the audio player
playIndex number 0 play index of the audio player
defaultPlayMode string order default play mode of the audio player options can be set to order,orderLoop,singleLoop,shufflePlay or omitted
mode string mini audio theme switch checkedText can be set to mini,full or omitted
once boolean false The default audioPlay handle function will be played again after each pause, If you only want to trigger it once, you can set 'true'
autoPlay boolean true Whether the audio is played after loading is completed. mobile devices are invalid autoplay-policy-changes
toggleMode boolean true Whether you can switch between two modes, full => mini or mini => full
drag boolean true audio controller is can be drag of the "mini" mode
seeked boolean true Whether you can drag or click the progress bar to play in the new progress.
showMiniModeCover boolean true audio cover is show of the "mini" mode
showMiniProcessBar boolean false audio progress circle bar is show of the "mini" mode
showProgressLoadBar boolean true Displays the audio load progress bar.
showPlay boolean true play button display of the audio player panel
showReload boolean true reload button display of the audio player panel
showDownload boolean true download button display of the audio player panel
showPlayMode boolean true play mode toggle button display of the audio player panel
showThemeSwitch boolean true theme toggle switch display of the audio player panel
showLyric boolean false audio lyric button display of the audio player panel
showMediaSession boolean false https://web.dev/media-session/
lyricClassName string - audio lyric class name
extendsContent ReactNode | boolean | string - Extensible custom content like <><button>button1</button> <button>button2</button></>
defaultVolume number 1 default volume of the audio player , range 0-1
loadAudioErrorPlayNext boolean true Whether to try playing the next audio when the current audio playback fails
responsive boolean true Whether to turn on the response mode, if set false, audio controller always show desktop ui
onAudioDownload function(audioInfo) - audio is downloaded handle
onAudioPlay function(audioInfo) - audio play handle
onAudioPause function(audioInfo) - audio pause handle
onAudioSeeked function(audioInfo) - When the user has moved/jumped to a new location in audio handle
onAudioVolumeChange function(volume) - When the volume has changed handle min = 0.0 max = 1.0
onAudioEnded function(currentPlayId,audioLists,audioInfo) - The single song is ended handle
onAudioAbort function(currentPlayId, audioLists, audioInfo) - audio load abort The target event like {...,audioName:xx,audioSrc:xx,playMode:xx}
onAudioProgress function(audioInfo) - audio play progress handle
onAudioError function(errMsg,currentPlayId, audioLists, audioInfo) - audio load failed error handle
onAudioReload function(audioInfo) - audio reload handle
onAudioListsChange function(currentPlayId,audioLists,audioInfo) - audio lists change handle
onAudioPlayTrackChange function(currentPlayId,audioLists,audioInfo) - audio current play track change handle
onAudioPlayModeChange function(playMode) - play mode change handle
onAudioListsPanelChange function(panelVisible) - audio lists panel change handle
onThemeChange function(theme) - theme change handle
onModeChange function(mode) - mode change handle
onAudioListsSortEnd function(oldIndex,newIndex) - audio lists sort end handle, use SortableJS
onAudioLyricChange function(lineNum, currentLyric) - audio lyric change handle
getContainer () => HTMLElement | Selectors document.body Return the mount node for Music player
getAudioInstance (instance: HTMLAudioElement) => void - get origin audio element instance , you can use it do everything
autoHiddenCover boolean false Auto hide the cover photo if no cover photo is available
onBeforeAudioDownload (audioInfo: ReactJkMusicPlayerAudioInfo) => Promise<TransformedDownloadAudioInfo> - transform download audio info before
clearPriorAudioLists boolean false Replace a new playlist with the first loaded playlist and reset playIndex to 0
autoPlayInitLoadPlayList boolean false Play your new play list right after your new play list is loaded turn false.
spaceBar boolean false Play and pause audio through space bar (Desktop effective).
showDestroy boolean false Destroy player button display
onBeforeDestroy function(currentPlayId,audioLists,audioInfo) - custom destroy handler before
onDestroyed function(currentPlayId,audioLists,audioInfo) - player destroyed handle
customDownloader function(downloadInfo: TransformedDownloadAudioInfo) - custom download handle
onCoverClick function(mode,audioLists,audioInfo) - audio cover clicked handle
onPlayIndexChange function(playIndex) - audio play index change handle
quietUpdate boolean false Detail
renderAudioTitle (audioInfo, isMobile) => ReactNode - use locale.audioTitle to set audio tag title, the api can render custom jsx element for display
mobileMediaQuery string (max-width: 768px) and (orientation : portrait) custom mobile media query string, eg use the mobile version UI on iPad. https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries
volumeFade { fadeIn: number(ms), fadeOut: number(ms) } - audio fade in and out. Detail
sortableOptions object {swap: true, animation: 100, swapClass: 'audio-lists-panel-sortable-highlight-bg'} SortableJs Options
restartCurrentOnPrev boolean false Restarts the current track when trying to play previous song, if the current time of the song is more than 1 second

💡 Custom operation ui

Support feature:

  • play
  • pause
  • reload
  • change play time
  • change playback rate
  • change volume
  • destroy audio player
  • toggle play
  • clear audio list
  • toggle play
  • play next audio
  • play prev audio
  • play audio by custom play index
  • update play index
  • SortableJS methods
class App extends React.Component {
  constructor() {
    this.audioInstance = null
  }
  render() {
    return (
      <>
        <ReactJkMusicPlayer
          getAudioInstance={(instance) => {
            this.audioInstance = instance
          }}
        />
        <button onClick={() => this.audioInstance.play()}>play</button>
        <button onClick={() => this.audioInstance.pause()}>pause</button>
        <button onClick={() => this.audioInstance.load()}>reload</button>
        <button onClick={() => this.audioInstance.currentTime = 40}>
          change current play time
        </button>
        <button onClick={() => this.audioInstance.playbackRate = 2}>
          change play back rate
        </button>
        <button onClick={() => this.audioInstance.volume = 0.2}>
          change volume
        </button>
        <button onClick={() => this.audioInstance.destroy()}>
          destroy player
        </button>
        <button onClick={this.audio.togglePlay}>toggle play</button>
        <button onClick={this.audio.clear}>clear audio lists</button>
        <button onClick={this.audio.playNext}>play next</button>
        <button onClick={this.audio.playPrev}>play prev</button>
        <button onClick={() => this.audio.playByIndex(1)}>play by index</button>
        <button onClick={() => this.audio.updatePlayIndex(1)}>
          update play index
        </button>
      </>
    )
  }
}

💡 Glass bg

<ReactJkMusicPlayer glassBg />

glass-1 glass-2

💡 Custom downloader

Default use downloadjs, you can use any download library

eg. https://www.npmjs.com/package/file-saver, or use download attribute

const customDownloader = (downloadInfo) => {
  const link = document.createElement('a')
  link.href = downloadInfo.src // a.mp3
  link.download = downloadInfo.filename || 'test'
  document.body.appendChild(link)
  link.click()
}

;<ReactJkMusicPlayer
  audioLists={[{ src: 'a.mp3' }]}
  customDownloader={customDownloader}
/>

// use onBeforeAudioDownload
const onBeforeAudioDownload = () => {
  return Promise.resolve({
    src: '1.mp3',
  })
}

const customDownloader = (downloadInfo) => {
  console.log(downloadInfo.src) // 1.mp3
}

;<ReactJkMusicPlayer
  customDownloader={customDownloader}
  onBeforeAudioDownload={onBeforeAudioDownload}
/>

💡 Destroy player

const onBeforeDestroy = (currentPlayId, audioLists, audioInfo) => {
  return new Promise((resolve, reject) => {
    // your custom validate
    if (window.confirm('Are you confirm destroy the player?')) {
      // if resolve, player destroyed
      resolve()
    } else {
      // if reject, skip.
      reject()
    }
  })
}

const onDestroyed = (currentPlayId, audioLists, audioInfo) => {
  console.log('onDestroyed:', currentPlayId, audioLists, audioInfo)
}

;<ReactJkMusicPlayer
  showDestroy
  onBeforeDestroy={onBeforeDestroy}
  onDestroyed={onDestroyed}
/>

💡 Media session

https://web.dev/media-session/

// so cool, so easy !!!
<ReactJkMusicPlayer showMediaSession />

💡 Internationalization

Version: 4.11.0

Source

import Locale from 'react-jinke-music-player/lib/config/locale'
// Two languages are provided by default
// one of zh_CN | en_US
<ReactJkMusicPlayer locale={Locale.zh_CN}/>
// <ReactJkMusicPlayer locale={'en_US'}/>

// Custom override
const customLocale = {
  playModeText: {
    order: '',
    orderLoop: '',
    singleLoop: '',
    shufflePlay: ''
  },
  openText: '',
  closeText: '',
  emptyText: '',
  clickToPlayText: '',
  clickToPauseText: '',
  nextTrackText: '',
  previousTrackText: '',
  reloadText: '',
  volumeText: '',
  playListsText: '',
  toggleLyricText: '',
  toggleMiniModeText: '',
  destroyText: '',
  downloadText: '',
  lightThemeText: '',
  darkThemeText: '',
  switchThemeText: '',
  removeAudioListsText: '',
  controllerTitle: '',
  emptyLyricText: '',
  clickToDeleteText: (name) => ``,
  audioTitle: ''
  // audioTitle: (audioInfo) => ``
}

<ReactJkMusicPlayer locale={customLocale}/>

// Support partial override, auto merge

<ReactJkMusicPlayer locale={{ audioTitle: "xxx" }}/>

💡 Customize Theme

import ReactJkMusicPlayer from 'react-jinke-music-player'
import 'react-jinke-music-player/lib/styles/index.less'
@primary-color: #31c27c;
@default-color: #d9d9d9;
@bg-color: #f7f8fa;
@border-color: #d9d9d9;
@panel-bg-light: #fff;
@controller-bg-light: #fff;
@music-player-panel-height: 80px;
@lists-panel-width: 480px;
@lists-panel-height: 410px;
@lists-panel-item-bg: #40444b;
@lists-panel-item-bg-light: #fff;
@panel-header-height: 50px;
@panel-bg: rgba(0, 0, 0, 0.7);
@font-color: #444;
@player-width: 80px;
@player-height: @player-width;
@base-color: rgba(255, 255, 255, 0.6);
@common-animate-type: cubic-bezier(0.43, -0.1, 0.16, 1.1);
@common-animate-time: 350ms @common-animate-type;
@progress-load-bar-bg-color: rgba(0, 0, 0, 0.11);
@progress-load-bar-bg-color-light: rgba(0, 0, 0, 0.06);
@progress-bar-bg-color-light: rgba(0, 0, 0, 0.09);
@progress-bar-bg-color-dark: #fff;
@player-lyric-color: @primary-color;
@player-lyric-font-size: 36px;
@player-lyric-font-size-mobile: 16px;
@player-lyric-z-index: 999;

Customize in webpack

// webpack.config.js

module.exports = {
  rules: [{
    test: /\.less$/,
    use: [
      ...
      {
      loader: 'less-loader',
+     options: {
+       modifyVars: {
+         'primary-color': '#444',
+         // or
+         'hack': `true; @import "your-less-file-path.less";`, // Override with less file
+       },
+       javascriptEnabled: true,
+     },
    }],
  }],
}

Customize in less file

@import 'react-jinke-music-player/lib/styles/index.less';
@import 'your-theme-file.less';

💡 Customize audio duration

Default: by this.audio.duration, if cannot get current play audio's duration, you can customize to set.

<ReactJkMusicPlayer audioLists={[{
  ...
  duration: 100.00
}]} />

💡 Customize player icon

export interface ReactJkMusicPlayerIcon {
  pause?: React.ReactNode | string
  play?: React.ReactNode | string
  destroy?: React.ReactNode | string
  close?: React.ReactNode | string
  delete?: React.ReactNode | string
  download?: React.ReactNode | string
  toggle?: React.ReactNode | string
  lyric?: React.ReactNode | string
  volume?: React.ReactNode | string
  mute?: React.ReactNode | string
  next?: React.ReactNode | string
  prev?: React.ReactNode | string
  playLists?: React.ReactNode | string
  reload?: React.ReactNode | string
  loop?: React.ReactNode | string
  order?: React.ReactNode | string
  orderLoop?: React.ReactNode | string
  shuffle?: React.ReactNode | string
  loading?: React.ReactNode | string
}

💡 Follow the theme of the system

<ReactJkMusicPlayer theme="auto" />

auto-theme

💡 Quiet update

/**
 * Don't interrupt current playing state when audio list updated
 * eg. (A) is current playing...
 * [A,B] => [A,C,B]
 * [A,B] => [A,B,C]
 *
 * if (A) not in updated audio lists
 * [A,B] => [C]
 * (C) is playing
 */

function App() {
  const [audioLists, setAudioLists] = useState([
    { musicSrc: 'A' },
    { musicSrc: 'B' },
  ])

  useEffect(() => {
    setTimeout(() => {
      setAudioLists([{ musicSrc: 'A' }, { musicSrc: 'C' }, { musicSrc: 'B' }])
    }, 1000)
  }, [setAudioLists])

  return (
    <ReactJkMusicPlayer
      quietUpdate
      clearPriorAudioLists
      audioLists={audioLists}
    />
  )
}

💡 Import in browser

<!DOCTYPE html>
<html lang="en">
  <head>
    <link
      rel="stylesheet"
      href="https://unpkg.com/[email protected]/assets/index.css"
    />
  </head>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/react-jinke-music-player.min.js"></script>
  <script>
    ReactDOM.render(
      React.createElement(ReactJkMusicPlayer),
      document.getElementById('root'),
    )
  </script>
</html>

💡 Server-Side Rendering

// components/Player.js
import React from 'react'
import ReactJkMusicPlayer from 'react-jinke-music-player'
import styles from 'react-jinke-music-player/assets/index.module.css'

export const Player = () => <ReactJkMusicPlayer />

// pages/_app.js
import dynamic from 'next/dynamic'
const PlayerWithNoSSR = dynamic(() => import('../components/Player'), {
  ssr: false,
})

💡 Customize mobile media query

eg. Use mobile UI on a iPad device

// Default '(max-width: 768px) and (orientation : portrait)'
<ReactJkMusicPlayer mobileMediaQuery="(max-width: 1024px)" />

💡 Audio volume fade in and fade out

<ReactJkMusicPlayer volumeFade={{ fadeIn: 500, fadeOut: 500 }} />

📝 Development

git clone https://github.com/lijinke666/react-music-player.git
yarn # npm install
yarn start # npm start
open `http://localhost:8084/`

⌛ Test case

npm run test

💡 AudioListProps

Like This

interface ReactJkMusicPlayerAudioListProps {
  name: string | React.ReactNode,
  musicSrc: string | () => Promise<string>,
  cover: string,
  singer?: string | React.ReactNode,
  duration?: number,
  lyric?: string,
  [key: string]: any
}>

💡 AudioInfo

Like This

interface ReactJkMusicPlayerAudioInfo {
  cover: string
  currentTime: number
  duration: number
  ended: boolean
  musicSrc: string
  muted: boolean
  name: string
  networkState: number
  paused: boolean
  played: any
  readyState: number
  startDate: any
  volume: number
  lyric: string
  [key: string]: any
}

👬 Contributors

Special thanks: @JeffreyCA

https://github.com/lijinke666/react-music-player/graphs/contributors

📄 License

MIT

react-music-player's People

Contributors

aniketbiswas21 avatar ballad89 avatar cacpgomes avatar demuxcrypto avatar dependabot-preview[bot] avatar dependabot[bot] avatar emulienfou avatar imgbotapp avatar jeffreyca avatar karnak19 avatar lijinke666 avatar nunojesus avatar rainyman2012 avatar semantic-release-bot avatar sparkhom avatar tahaygun 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  avatar  avatar  avatar  avatar  avatar  avatar

react-music-player's Issues

iOS issues

on iOS,
1 . autoplay isn't working.
2. Seekbar shows NAN on total time.

Typo

This function autdioSeeked appears several times in codebase. I think it should be audioSeeked (without the additional 't').

Toggle Mobile Player

Is there any way to toggle off mobilePlayer when the browser screen is small?
I don't see it in the option settings.

onAudioDownload: modify object BEFORE running core code

The onAudioDownload function is not very useful as it is called AFTER the redirect. The function could be useful for modifying the audio URL, for example appending download=1, or opening the download in a new window. To do this, the function should call the user function (if exists) first and then use the modified object to run the core code.

I hope this makes sense. And maybe this cannot be modified now due to backwards compatibility / functionality change, but then maybe a new function called something like onBeforeAudioDownload could be introduced to do this behavior.

Right now, clicking the download button will open the audio file in the same tab and thus killing the player and the entire React UI, and then my Chrome shows the mp3 in it's built-in player. With this function I could open in a new tab and append to the URL so that the platform that holds the mp3 will ask Chrome to download the mp3 file.

How to play/pause song ?

Hi,

In my code
<ReactJkMusicPlayer ref={this.player} {...params} />

then i can use this.player.playxx()/pause this way. How to do that ? Thank you !

Close button on mobile mode is not working

When resizing my browser window to trigger the mobile version of the player skin, the close button (top right-hand side) is not doing anything and keeps the whole player on top of the website which stops user navigation.

<QUESTION>

How To Get Index Or ID Of Music Playing?

Current Playlist doesn't re-render

Hello,
How to play song that was just added to playlist ?

I changed clearPriorAudioLists to true then the song was added to the beginning and play that song. However, when I add the song again, it did nothing

buttons of player on mobile mode don't work

I'm using create-react-app, node version 10.15.1, npm version 6.4.1.

When I install the player through npm then the buttons of the music player will stop working on mobile mode.
P.S. (when I use the source code directly the issue of the mobile buttons get solved but another issues will come)

------- package.json -------
{
"name": "musicfromnode",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.5",
"react-dom": "^16.8.5",
"react-jinke-music-player": "^4.2.1",
"react-scripts": "2.1.8"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}

------- Player.js -------

import React from "react";
import Player from "react-jinke-music-player";
import "react-jinke-music-player/assets/index.css";
import FaHeadphones from "react-icons/lib/fa/headphones";

const options = {...
};

class MusicPlayer extends React.Component {
state = {
params: options
};
constructor(props) {
super(props);
this.state = {
params: options
};
}

render() {
const { params } = this.state;
return (


<Player {...params} />

);
}
}

export default MusicPlayer;

------- App.js -------

import React, { Component } from "react";
import Player from "./Player";

class App extends Component {
render() {
return (




);
}
}

export default App;

.progress-bar needs a background-color

When using this player in a project where you are using a different css library that contains .progress-bar background-color, the player uses it, effectively messing the lovely theme. Please explicitly add this in the player css, for example for light theme:

.react-jinke-music-player-main.light-theme .progress-bar-content .progress-bar{
  background-color: white;
}

Abilty to download audio/wav blob urls

Description

The abilty to download audio/wav blob urls using the in built download function (downloadjs)

Reason

When passing a audio/wav blob url to the player i.e. "musicSrc":"blob:https://redacted/fe8ef69b-4e28-499d-8429-65914646eba1". When you click the download function the current player 4.7.2 downloads a .zip file which you cannot open. if you use onBeforeAudioDownload to set the mimeType and filename you get a 1kb wav file which cannot be played.

Current Workaround

    /**
     * Disable the built in download function to allow
     * us to handle this below in the onBeforeAudioDownload
     * function
     * @returns {void} void
     */
    objPlayerProps.onAudioDownload = () => {};

    objPlayerProps.onBeforeAudioDownload = (objAudioInfo) => {
      /**
       * Using the built in `onAudioDownload` alone or along with
       * the `onBeforeAudioDownload` to rename filename and mimeType does not work
       *
       * what we should be able to do here is just set the mimeType and filename
       * and then the download should work. 
       * If using `onAudioDownload` alone you get an invalid .zip file which cannot be opened
       * if using `onBeforeAudioDownload` you get a 1kb wav file which cannot be played
       * if fixed @see https://github.com/lijinke666/react-music-player/issues/80
       * we can then use
       * @example
       * return Promise.resolve({
       *  filename: `${objAudioInfo.name}.wav`,
       *  mimeType: 'audio/wav',
       *  src: objAudioInfo.musicSrc,
       * });
       *
       * Create our own download link as the one built
       * into this player downloads an invalid .zip file
       * when using a audio blob.
       */
      if (objAudioInfo.musicSrc) {
        FileSaver.saveAs(objAudioInfo.musicSrc, `${objAudioInfo.name}.wav`);
      }
      /**
       * onBeforeAudioDownload needs to rejects its promise to cancel the
       * standard downloadjs function
       */
      return Promise.reject();
    };

Possible Fix

Change from using downloadjs to https://www.npmjs.com/package/file-saver

Change the audio when playing by update the list.

When i change the state,i want to play the song that just added to the list,how can i do that?It's update the list,but still play the first song.
<ReactJkMusicPlayer className = "audioControl" audioLists = { [ { name:this.state.song.nameSong, musicSrc:'http://localhost:3001/song/' + this.state.song.id, }] } autoPlay={false} mode="full" />

Feature: Playback at different speed

Hi,

Nice player.

I'm considering to use this player for non-music files (recordings).

HTML5 audio supports playing a different speeds with setPlaybackRate(2) for double speed for example.

Would you consider adding that with a UI button to change speed?

The UI button could be configured with an array of objects setting the speed and the label for the button.

Make it possible to hide cover photo/image

Our recordings do not have a cover photo and the only fairly sensible cover photo to show is a logo. Currently, when no cover is available, the player renders and empty round spot. But the cover photo (all the way to the left in the full player) also takes space in the UI, so it would be nice to either;

  1. Auto-hide the cover photo if no cover photo is available
  2. Make it possible to configure if it's shown or not, which would allow us to add a logo image and have it shown in the mini-player while hiding it in the full player to gain UI space

NB: This will be more feature request for now. And yes, I do anticipate to try doing one or more of these myself as a PR if time permits. Mostly registering them here to hopefully get your interest into getting these features in.

Play/Pause from custom Button doesn't sync with the player button

Trying to control play and pause with custom buttons doesn't work .Issue is the audio gets paused/played if i do this.audio.pause()/this.audio.play() . But the play/pause button doesn't sync with audio play/pause.

this.state = {
audio:null,
options: {
audioLists: [
{
singer: "Jay Chou",
cover: this.props.thumbnail,
musicSrc: this.props.streamUrl,
},
],
autoPlay: true,
mode: "full",
clearPriorAudioLists: true,
},
defaultPosition: {
bottom: 0,
},
};
togglePlay =()=>{
this.state.audio.pause()
}
<ReactJkMusicPlayer {...options} getAuioInstance={(instance=>this.setState({audio:instance})}/>
<button onClick={()=>this.togglePlay}>play

Cannot Fire onPause, onEnd, etc

I'm new to React. I have my component set up this way and it fires the function on mount. What am I doing wrong? Thanks!

<ReactJkMusicPlayer ... onAudioProgress={this.trackTime('progress')} onAudioEnd={this.trackTime('end')} onAudioPause={this.trackTime('pause')} />

how to hide the loading circle

Hey, thanks for creating this project but I have gone through a problem where the loading circle just swirling over the place, can you please tell me how to disable or hide it.

样式影响到ant-design

antd的button,a标签等,变成reset的默认样式,只import组件不引入css也一样。

Logotype

Hello, I like to contribute with graphic designs, in opensource projects, so if you need something from me like a logotype or something else just say it, Im here ready to help you.
Love the screenshots of your player
Greetings!
Nuno Jesus

Player won't load music during update audioList state with redux.

Hey, got a problem with updating track list update using redux.

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import ReactJkMusicPlayer from 'react-jinke-music-player';
import '../music-player/player.css';

@connect(({ PlayerTracks }) => ({
  tracks: PlayerTracks.tracks,
}))
export default class Container extends PureComponent {
  static propTypes = {
    tracks: PropTypes.array,
  }

  static defaultProps = {
    tracks: null,
  }

  render() {
    const { tracks } = this.props;
    return (
      <div>
        <ReactJkMusicPlayer drag={false} showThemeSwitch={false} mode='full'
                            showDownload={false} toggleMode={false}
                            audioLists={tracks} autoPlay={false}/>,
      </div>
    );
  }
}

If I have initial state like an empty array future update of audioList break ability to play any sound. If I define initial array with some data it's ok, but if I try to clearely update whole list smth went wrong:(
P.S. player is really awesome, thanks!:)

Scope ul in index.css

I'm using this awesome component within an app I'm building, but I noticed the styles for unordered list is not scoped to just the player; therefore, the global style inherits it. Can you scope it? Thanks!

Gapless playback

Description

Are you planning to support Gapless playback? I'm planning to add this player to my music server and this would be great for playing live albums!

By the way: Thanks for this awesome player!

Uncaught error when removing last item in playlist

To recreate:

  1. Have a playlist with songs.
  2. Open the list
  3. Remove items, one by one
  4. When removing the last item, watch the console and see the following error thrown
index.js:1509 Uncaught Error: The error you provided does not contain a stack trace.
    at B (index.js:1509)
    at G (index.js:1816)
    at index.js:1831
    at index.js:1850
    at index.js:1343
B @ index.js:1509
G @ index.js:1816
(anonymous) @ index.js:1831
(anonymous) @ index.js:1850
(anonymous) @ index.js:1343
applications:1 Uncaught (in promise) DOMException: Failed to load because no supported source was found.

New features to the player

Hey @lijinke666 , here is the list of features that could be awesome for your player

  • On track list state change start auto-playing this list.
    For the first case you have an 3 tracks that loaded to your list, when list changed, player automatically starts playing from first track of the list
  • Make some kind of flag in the request array which track to play.
    You have array of tracks info, as for now they played from the first one, we need to add some flag to alert the player that tracks playlist should start from some index
  • Make track list bar customizible, I mean, we need to add some delete button for modifying this list if you want to drop this track from playing queue.
  • Ordering in play queue, need to add some kind of track position dragging, click on track, drag out it to the first position of the queue etc.

Thanks a lot!

cannot install ?

if you try install the pacekage

yarn add react-jinke-music-player

but have some problems, like this ?

[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
error http://registry.npm.taobao.org/capture-stack-trace/download/capture-stack-trace-1.0.1.tgz: Integrity check failed for "capture-stack-trace" (computed integrity doesn't match our records, got "sha1-psC74fOPOqC5Ijjstv9Cw0TUE10=")

please try user npm install

rm -rf node_modules
npm install react-jinke-music-player

+ [email protected]

This should solve the problem of not being able to install . good luck !

onClick on a div , play another music ( call back to pause and play another index)

hello guys , i have 6 music div , and i want to play another music , when clicked on play button .
but i have not any callback function to say " please stop musiccccc, then , play THIS index.
can you please look at my code?
`class Latests extends Component {

play = (image, music, index) => {
    console.log(image, music, index);
    this.setState({play: true, music: music, image: image , index: index});
};

constructor(props, context) {
    super(props, context);
    this.state = {
        play: false,
        image: "",
        music: "",
        index:0
    };
}

render() {
    const {play, index} = this.state;

    const audioList = [
        {
            cover: t1,
            musicSrc: musicSource,
            name: "Canon (piano version)",
            volume: 100,
            networkState: 1,
            readyState: 4,
            played: {length: 1}
        },
        {
            cover: t2,
            musicSrc: musicSource,
            name: "Canon (piano version)2",
            volume: 100,
            networkState: 1,
            readyState: 4,
            played: {length: 1}
        },
        {
            cover: t3,
            musicSrc: musicSource,
            name: "Canon (piano version)3",
            volume: 100,
            networkState: 1,
            readyState: 4,
            played: {length: 1}
        },
        {
            cover: t4,
            musicSrc: musicSource,
            name: "Canon (piano version)4",
            volume: 100,
            networkState: 1,
            readyState: 4,
            played: {length: 1}
        },
        {
            cover: t5,
            musicSrc: musicSource,
            name: "Canon (piano version)5",
            volume: 100,
            networkState: 1,
            readyState: 4,
            played: {length: 1}
        },
        {
            cover: t6,
            musicSrc: musicSource,
            name: "Canon (piano version)6",
            volume: 100,
            networkState: 1,
            readyState: 4,
            played: {length: 1}
        }
    ];

    return (
        <div className="row align-content-center">
            <div className='col-12 row justify-content-center d-flex'>
                <div className={"col-3 m-1"}>
                    <LatestsCard index={0} music={musicSource} playMusic={this.play} name={"WoW From OwO"} image={t1}/>
                </div>
                <div className={"col-3 m-1"}>
                    <LatestsCard index={1} music={musicSource2} playMusic={this.play} name={"WoW From OwO22"} image={t2}/>
                </div>
                <div className={"col-3 m-1"}>
                    <LatestsCard index={2} music={musicSource} playMusic={this.play} name={"WoW From OwO"} image={t3}/>
                </div>
                <div className={"col-3 m-1"}>
                    <LatestsCard index={3} music={musicSource} playMusic={this.play} name={"WoW From OwO"} image={t4}/>
                </div>
                <div className={"col-3 m-1"}>
                    <LatestsCard index={4} music={musicSource} playMusic={this.play} name={"WoW From OwO"} image={t5}/>
                </div>
                <div className={"col-3 m-1"}>
                    <LatestsCard index={5} music={musicSource} playMusic={this.play} name={"WoW From OwO"} image={t6}/>
                </div>
            </div>
            {play &&
            <ReactJkMusicPlayer
                onAudioPlayTrackChange={(audioInfo) => console.log(audioInfo)}
                seeked={true}
                preload={true}
                mode={"full"}
                glassBg={true}
                defaultPlayIndex={index}
                defaultPosition={{bottom: 60, left: 0}}
                audioLists={audioList}
            />
            }
        </div>
    );
}

}`

Player breaks when you add a new song to the playlist

  getPlayInfo = (audioLists = []) => {
    const _audioLists = audioLists.map(info => {
      return {
        ...info,
        id: uuId()
      };
    });
    const playIndex = Math.max(
      0,
      Math.min(audioLists.length, this.props.defaultPlayIndex)
    );
    const playId = this.state.playId || _audioLists[playIndex].id;
    const { name = "", cover = "", singer = "", musicSrc = "" } =
      _audioLists.find(({ id }) => id === playId) || {};
    return { name, cover, singer, musicSrc, audioLists: _audioLists, playId };
  };

The method above gets called every time a new track is added to an already rendered player. So that means every track in the list gets a new uuid everytime
So that means playId would refer to a uuid which has been overwritten, hence this _audioLists.find(({ id }) => id === playId) never matches.

In essence what happens is when a song is playing and you add a new song to the playlist the resulting state is always { name = "", cover = "", singer = "", musicSrc = "" } which causes the player to error

Optional button inside player UI to fully close/kill/destroy player

While I appreciate the mini player and full player swap and plan to actively use that feature, I think a proper close function would be nice. This could be an optional button, hidden by default if you like and be an "X" type icon all the way to the right, and an "X" in the corner of the mini player.

This would simply kill the component or do a callback to a function passed in as a prop to the player.

I know you have responded to this before, and that it's possible to simply not render the player from my own code, but that does not make it easy for me to let the user show and actively close the player. Once it's floating in one way or the other, I cannot let the user close the player from within the player, unless I do a hack with a floating close button, but that really is not optimal and having it inside the player, would be much better for usability.

I was thinking that clicking the button could be a flexible prop that defaults to destroying itself, but a function could also be passed which could be a prop passed function so I can kill it from my calling component. Hope it makes sense...

Firefox Audio Src

In Firefox and Edge, the audio source does not load.

Console:
Invalid URI. Load of media resource failed.

DOM:
<audio class="music-player-audio" src="https://domain.com/path_to_mp3"></audio>

It works fine in Chrome. Any thoughts? I'm loading the audioList from a fetch which updates the state in the component.

AudioInfo has ID field ?

Let me show you my intent:
I add a song named "ABC" with ID: 123 to audioLists. Then when I pause that song in music player, the state song with same ID will change to paused as well

//audio pause handle

  onAudioPause(audioInfo) {
       const currenSong = findSong(audioInfo.ID)
       currentSong.playing = false
       setCurrentSong(currentSong)
  },

How to do that ? Thank you ! I can find the corresponding song by name but I am assuming there are same name songs

I can't yarn to develop this project

localhost:react-music-player-master jinglmalan$ yarn
yarn install v1.15.2
[1/4] 🔍 Resolving packages...
warning [email protected]: This version of react-dom/server contains a minor vulnerability. Please update react-dom to 16.4.2+. Learn more: https://fb.me/cve-2018-6341
[2/4] 🚚 Fetching packages...
error http://registry.npm.taobao.org/capture-stack-trace/download/capture-stack-trace-1.0.1.tgz: Integrity check failed for "capture-stack-trace" (computed integrity doesn't match our records, got "sha1-psC74fOPOqC5Ijjstv9Cw0TUE10=")
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

Q: Can you help me? sir. what's the matter with that?

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.