Danh sách nhạc trên soundcloud
Danh sách nhạc trên soundcloud

Tải Nhạc Nào Mình Cùng Lên Xe Buýt: Hướng Dẫn Fetch Dữ Liệu Từ SoundCloud API và Xây Dựng Music Player với React/Redux

Cuộc hành trình học React/Redux đã gần đến hồi kết. Bài viết này sẽ hướng dẫn cách lấy dữ liệu từ SoundCloud API và xây dựng một music player đơn giản. Nào mình cùng lên xe buýt, bắt đầu hành trình khám phá!

Danh sách nhạc trên soundcloudDanh sách nhạc trên soundcloud

Fetch Dữ Liệu và Hiển Thị

Sau khi đã authenticated với SoundCloud API, bước tiếp theo là lấy dữ liệu bài hát về và hiển thị.

Đầu tiên, cần tham khảo API docs của SoundCloud để xác định API endpoint cho việc tải danh sách bài hát của người dùng. Sau khi authentication thành công, chúng ta sẽ gọi API này và cập nhật dữ liệu thông qua action setTracks.

Trong file actions/auth.js, thêm các thành phần để lấy danh sách bài hát:

// ...
import { setTracks } from '../actions/track';
// ...

export function auth() {
  return (dispatch) => {
    SoundCloud.connect().then((session) => {
      dispatch(fetchMe(session));
      dispatch(fetchTracks(session));
    });
  }
}
// ...

function fetchTracks(session) {
  return (dispatch) => {
    fetch(`${API_HOST}/me/activities?limit=20&offset=0&oauth_token=${session.oauth_token}`)
    .then((res) => res.json())
    .then((data) => {
      dispatch(setTracks(data.collection));
    });
  }
}

Chúng ta sẽ gọi API activities và lấy 20 phần tử đầu tiên. fetchTracks sẽ được thực hiện asynchronous cùng với fetchMe (lấy thông tin người dùng) sau khi authentication thành công.

Chỉnh Sửa Presenter và Tạo Component Track

Vì dữ liệu từ API thực tế khác với dữ liệu hard code ban đầu, chúng ta cần chỉnh sửa presenter của TrackList. Để tiện lợi hơn, ta sẽ tách phần hiển thị track thành một component mới tên là Track trong file components/TrackList/Track.js:

import React, { PropTypes, Component } from 'react';

export default class Track extends Component {
  static propTypes = {
    track: PropTypes.object.isRequired
  }

  render() {
    const { origin: { artwork_url, title } } = this.props.track;
    return (
      <div>
        <img src={artwork_url} alt={`Bìa album bài hát ${title}`} />
                <button onClick={this._play.bind(this)}>Play</button> {/* Nút play được thêm vào đây */}      
        {title}
      </div>
    )
  }
}

Component này nhận prop là track và hiển thị artwork, title, và nút play của bài hát.

Xây Dựng Music Player

Để phát nhạc khi nút Play được click, chúng ta sẽ sử dụng tag Audio của HTML5. Vì không nên đặt tag này trong mỗi Track, chúng ta sẽ đặt nó ở higher order component là TrackList.

Trong file TrackList.js, thêm tag audio:

// ...
render() {
  // ...
  return (
    <div>
      {/* ... */}
      <audio id='player' ref={(player) => { this.player = player; }} src={activeTrack ? `${activeTrack.origin.stream_url}?client_id=${this.props.clientId}` : ''} ></audio> {/* activeTrack được kiểm tra trước khi sử dụng */}
      {/* ... */}  
    </div>    
  );
}
// ...

Thêm State activeTrack

Để biết track nào đang được chơi, ta cần một state activeTrack trong reducer tracks. State này sẽ được cập nhật bởi action playTrack.

Trong file reducers/tracks.js, thêm state activeTrack và action TRACK_PLAY:


import {ActionTypes} from '../core/constants';

const initialState = {
  tracks: [],
  activeTrack: null
};

export default function(state = initialState, action) {
  switch (action.type) {
    case ActionTypes.SET_TRACKS:
      return {...state, tracks: action.tracks};

        case ActionTypes.TRACK_PLAY:
            return {...state, activeTrack: action.track}

    default:
            return state;
 }
}

Trong file actions/track.js, thêm action playTrack:

// ...
export function playTrack(track) {
  return {
    type: ActionTypes.TRACK_PLAY,
    track
  };
}

Kết Nối Action với Component

Thêm action playTrack vào @connect của TrackList và truyền xuống Track. Trong Track, khi nút Play được click sẽ gọi action playTrack.

// ... Track.js
_play() {    
   this.props.play(this.props.track.origin);
}
// ...

Phát Nhạc

Cuối cùng, trong componentDidUpdate của TrackList, chúng ta sẽ kiểm tra activeTrack. Nếu có, gọi hàm play() của audio tag để phát nhạc.

// ...TrackList.js
componentDidUpdate() {    
  if(this.props.tracks.activeTrack){
     this.player.src = `${this.props.tracks.activeTrack.stream_url}?client_id=${this.props.clientId}`;
     this.player.play();
  }  
}
//....

Vậy là chúng ta đã hoàn thành việc xây dựng một music player đơn giản với React/Redux.

Tài liệu tham khảo:

https://www.robinwieruch.de/the-soundcloud-client-in-react-redux/

Comments

No comments yet. Why don’t you start the discussion?

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *