Các chức năng + Phát, dừng và skip bài hát. + Quản lí bài hát dựa vào album, artist, songs. + Quản lí danh sách phát nhạc + Phát nhạc theo tuần tự playlist, lặp bài, suffle playlist nhạc. + Drag bài hát vào phần mềm. + Search theo bài hát, artists, album. + Dựng playlist đã nghe gần đây, playlist được nghe nhiều nhất. + Tự động tải hình ảnh album dựa vào tên album có sẵn
Trang 1ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
BÁO CÁO ĐỒ ÁN NGÔN NGỮ LẬP TRÌNH JAVA
ĐỀ TÀI MEDIA PLAYER
TP Hồ Chí Minh, 13 tháng 06 năm 2018
Giảng viên hướng dẫn: ThS Lê Thanh Trọng Sinh viên 1 : Lê Đức Tiến – 15520881 Sinh viên 2 : Dương Phước Hải Thọ - 15520851 Sinh viên 3 : Đỗ Thành Thắng - 15520787
Trang 2NHẬN XÉT CỦA GIÁO VIÊN HƯỚNG DẪN
… , ngày tháng năm 2018
Người nhận xét
(Ký tên)
Trang 3LỜI CẢM ƠN
Để có được sự thành công trong môn học và hoàn thành tốt đồ án cuôi kỳ - ứng dụng
“Music Player” chúng em đã nhận được rất nhiều sự giúp đỡ của các quý thầy cô và bạn bè
Tỏ lòng biết ơn sâu sắc, chúng em xin chân thành cảm ơn những giảng viên ở khoa Công nghệ phần mềm – Đại học Công Nghệ Thông Tin đã cùng với tri thức và tâm huyết của mình truyền đạt vốn kiến thức quý báu cho chúng em trong suốt thời gian học tập tại trường Trong học kỳ này, chúng em được tiếp cận với môn học “Công nghệ phần mềm chuyên sâu” – môn học rất hữu ích đối với sinh viên khoa Công nghệ phần mềm Và đặc biệt, quá trình thực hiện đồ án môn học đã giúp chúng em nâng cao kiến thức, trải nghiệm thực tế việc xây dựng một website đơn giản và một phần nào có thể giúp đỡ được nhiều người khi sử dụng sản phẩm của nhóm
Chúng em xin chân thành cảm ơn thầy Lê Thanh Trọng đã tận tâm hướng dẫn chúng
em qua từng buổi học trên lớp Nếu không có những lời hướng dẫn, chỉ bảo của thầy thì chúng
em nghĩ quá trình hoàn thiện bài báo cáo này của chúng em sẽ gặp nhiều vấn đề và khó khăn hơn
Do kiến thức và khả năng của chúng em còn nhiều hạn chế, vì vậy không tránh khỏi những thiếu sót, yếu kém Chúng em rất mong nhận được những ý kiến đóng góp quý báu của thầy để kiến thức của chúng em được hoàn thiện hơn
Sau cùng, chúng em xin kính chúc quý thầy cô ở khoa Công nghệ phần mềm và thầy
Lê Thanh Trọng thật dồi dào sức khỏe, niềm tin để tiếp tục thực hiện sứ mệnh cao đẹp của mình là truyền đạt kiến thức cho thế hệ mai sau
Trân trọng
Trang 4i
MỤC LỤC
MỤC LỤC i
1.1 Trình chạy nhạc Media Player ii
1.2 Các chức năng ii
2 PHÂN TÍCH VÀ THIẾT KẾ iii
2.1 Phân tích chức năng iii
2.1.1 Initialize MusicPlayer iii
2.1.2 Artists iii
2.1.3 Album vii
2.1.4 Songs viii
2.1.5 Tìm kiếm theo artist, album, tên bài hát x
2.1.6 Pause, Skip, Previous Songs xi
2.1.7 Playlist, Recently Played Playlist, Most Played Playlist xiii
2.1.8 Loop, shuffle, volume của bài hát xv
2.2 Thiết kế phần mềm xvi
2.2.1 Artists xvi
2.2.2 Album xviii
2.2.3 Songs xx
2.2.4 Tìm kiếm theo artist, album, tên bài hát xxi
2.2.5 Pause, Skip, Previous Songs xxii
2.2.6 Playlist, Recently Played Playlist, Most Played Playlist xxiii
2.2.7 Loop, shuffle, volume của bài hát xxv
4.CÀI ĐẶT xxvi
4.1 Nền tảng công nghệ xxvi
5 KẾT LUẬN xxvi
5.1 Kết quả đạt được xxvi
5.2 Hạn chế xxvi
5.3 Hướng phát triển xxvi
6 PHÂN CÔNG CÔNG VIỆC xxvii
7 TÀI LIỆU THAM KHẢO xxvii
Trang 5ii
1 GIỚI THIỆU
1.1 Trình chạy nhạc Media Player
Trong thời đại ngày nay, âm nhạc là một thứ gần như không thể thiếu đối với con người, thậm chí là động vật Các ca sĩ, nhạc sĩ … ngày càng có nhiều cơ hội dễ trình diễn sản phẩm của họ
Việc quản lí nhiều bài hát, nhiều ca khúc, album của ca sĩ, nhạc sĩ trở nên cần thiết hơn Người dùng có thể quản lí một cách thỏa mái và dễ dàng toàn bộ những bài hát, album hay ca
sĩ mà mình yêu thích Bật phát nhạc ở desktop offline và tận hưởng cuộc sống
Từ đó chúng tôi quyết định cho ra phần mềm quản lí media player, quản lí theo album, bài hát, ca sĩ và playlist Giúp người dùng dễ dàng thao tác, giao diện dễ sử dụng và hiệu ứng sống động cùng âm thanh chất lượng
1.2 Các chức năng
+ Phát, dừng và skip bài hát
+ Quản lí bài hát dựa vào album, artist, songs
+ Quản lí danh sách phát nhạc
+ Phát nhạc theo tuần tự playlist, lặp bài, suffle playlist nhạc
+ Drag bài hát vào phần mềm
+ Search theo bài hát, artists, album
+ Dựng playlist đã nghe gần đây, playlist được nghe nhiều nhất
+ Tự động tải hình ảnh album dựa vào tên album có sẵn
Trang 6• Tìm đường dẫn đến file library.xml
• Kiểm tra giá trị file trong folder thực và library.xml có giống nhau không để cập nhật
• Cập nhật library(sử dụng util.XMLEditor)
• Nếu đường dẫn không có file âm nhạc, yêu cầu người dùng import đường dẫn khác
Bước 3: Nhập danh sách bài hát -> album -> artist, playlist vào class Library để quản lí Bước 4: Khởi tạo danh sách chơi hiện tại để cập nhật bài hát đầu tiên
Bước 5: Kiểm tra bài hát có tồn tại các hình ảnh ca sĩ, album Nếu không, tự động download image từ cloud xuống
Bước 6: Sau khi đã đưa dữ liệu vào library class Khởi tạo giao diện fxml và Main Controller
để quản lí event
2.1.2 Artists
2.1.2.1 selectView(Event e)
Khi người dùng click vào HBox Artists thì sự kiện selectView(Event e) được gọi
Hàm HBox eventSource = ((HBox)e.getSource()); Sẽ bắt sự kiện click vào HBox Artists và tiến hành thêm CSS cho lớp Control trước đó
Hàm loadView(eventSource.getId()); sẽ load SubView tương ứng với HBox Artists, tạo ra file Aritists.fxml tương ứng
2.1.2.2 VBox createCell(Artist artist)
Tạo ra các artist-cell dựa vào thông tin như Title, Artist Image, artistImageProperty của đối tượng artist Tạo ra VBox dựa vào các thông tin trên và hiển thị trên TableView
Trang 7iv
2.1.2.3 class Artist implements Comparable<Artist>
class Aritist gồm các thuộc tính như:
private String title;
private ArrayList<Album> albums;
private Image artistImage;
private SimpleObjectProperty<Image> artistImageProperty;
Tạo constructor cho class Aritist
public Artist(String title, ArrayList<Album> albums) {
this.title = title;
this.albums = albums;
this.artistImageProperty = new SimpleObjectProperty<>(getArtistImage());
}
Trong đó aritistImageProperty sẽ được gán giá trị bằng getArtistImage();
public Image getArtistImage() {
if (artistImage == null) {
try {
File file = new File(Resources.JAR + "/img/" + this.title + ".jpg");
artistImage = new Image(file.toURI().toURL().toString());
if (artistImage.isError()) {
file.delete();
artistImage = new Image(Resources.IMG + "artistsIcon.png");
}
} catch (Exception ex) {
File file = new File(Resources.JAR + "/img/" + this.title + ".jpg");
Trang 8v
2.1.2.4 Dùng API để download Artist Image
public void downloadArtistImage()
2.1.2.5 void showAllSongs(Artist artist, boolean fromMainController)
Duyệt qua tất cả các album của artist, thêm tất cả các bài hát của album đó vào danh sách bài hát
Thực hiện sắp xếp danh sách các bài hát đó theo thứ tự alphabet
Hiển thị danh sách bài hát vào khung tableView bài hát
2.1.2.6 public void play()
Kiểm tra nếu Album đã được chọn thì đưa tất cả các bài hát đó vào danh sách phát Ngược lại nếu chưa có lựa chọn Album thì sẽ lấy tất cả các bài hát trong tất cả các album của Artist đó
Play nhạc nếu thuộc tính MusicPlayer.isShuffleActive()==true thì nhạc sẽ được play ngẫu nhiên, ngược lại sẽ được play theo thứ tự alphabet
2.1.2.7 Animation
Scroll danh sách Artist:
Animation scrollAnimation = new Transition() {
{
setCycleDuration(Duration.millis(500)); }
protected void interpolate(double frac) {
double vValue = startVvalue + ((finalVvalue - startVvalue) * frac);
artistListScrollPane.setVvalue(vValue);
}
};
Trang 9vi
Animation Load danh sách Artist
private Animation albumLoadAnimation = new Transition() {
{
setCycleDuration(Duration.millis(250));
setInterpolator(Interpolator.EASE_BOTH);
}
protected void interpolate(double frac) {
double curHeight = collapsedHeight + (expandedHeight - collapsedHeight) *
Animation Unload danh sách Artist
private Animation albumUnloadAnimation = new Transition() {
{
setCycleDuration(Duration.millis(250));
setInterpolator(Interpolator.EASE_BOTH);
}
protected void interpolate(double frac) {
double curHeight = collapsedHeight + (expandedHeight - collapsedHeight) * (1 - frac);
Trang 10Hàm loadView(eventSource.getId()); sẽ load SubView tương ứng với HBox Albums, tạo ra file Albums.fxml tương ứng
2.1.3.2 VBox createCell(Album album, int index)
Tạo ra các ô album dựa vào thông tin như Title, artwork của đối tượng album
Hiện thị các thông tin trên trên TableView
2.1.3.3 Class Album trong package Model
- Implement interface Comparable
- Gồm các thuộc tính
private int id;
private String title;
private String artist;
private Image artwork;
private ArrayList<Song> songs;
private SimpleObjectProperty<Image> artworkProperty
Trang 11viii
2.1.3.4 void downloadArtwork()
Tải artwork cho album từ internet theo tên ca sĩ và tên album sử dụng API
audioscrobler
2.1.3.5 Animation void populateSongTable(VBox cell, Album selectedAlbum)
Hiện danh sách bài hát (expandAnimation)
Ẩn danh sách bài hát (collapseAnimation)
2.1.4 Songs
2.1.4.1 Song data
Cấu trúc class một bài hát
private int id; //ID bài hát
private SimpleStringProperty title; //Tên bài hát
private SimpleStringProperty artist; //Tên ca sĩ
private SimpleStringProperty album; //Tên album
private SimpleStringProperty length; //Độ dài bài hát string
private long lengthInSeconds; //Độ dài tính bằng giây
private int trackNumber; //Số track trong album
private int discNumber; // Số đĩa
private SimpleIntegerProperty playCount; //Số lượng được chơi
private LocalDateTime playDate; //Ngày chơi
private String location; //Vị trí lưu file
private SimpleBooleanProperty playing; //Có đang chơi
private SimpleBooleanProperty selected; //Bài hát có đang được lựa chọn
2.1.4.1 SongsController
// Initializes table view scroll bar
private ScrollBar scrollBar;
// Keeps track of which column is being used to sort table view and in what order
(ascending or descending)
private String currentSortColumn = "titleColumn";
private String currentSortOrder = null;
private Song selectedSong;
Trang 12ix
Các sự kiện trong TableView ScrollBar
Click Row: Double click row song để bật bài hát được chọn
ControlDown Row: Cho phép chọn nhiều bài hát bằng cách nhấn ctrl, có thể kéo vào playlist isShiftDown Row: Cho phép chọn nhiều bài hát bằng phím shift, có thể kéo vào playlist để chơi nhạc
EnterPress: Chơi bài hát, hàng đang được chọn
2.2.4.3 Chơi bài hát được chọn
public void play() {
Song song = selectedSong; //Bài hát được chọn
ObservableList<Song> songList = tableView.getItems();
if (MusicPlayer.isShuffleActive()) { //Kiểm tra có xáo bài
2.1.4.4 Animation Scroll click leter
Override lại interface scroll để có thể thực hiện chức năng sort theo chữ cái Thêm hiệu ứng
Trang 13Thêm animation khi nhấn letter
Animation scrollAnimation = new Transition() {
{
setCycleDuration(Duration.millis(500));
}
protected void interpolate(double frac) {
double vValue = startVvalue + ((finalVvalue - startVvalue) * frac);
scrollBar.setValue(vValue);
}
};
2.1.5 Tìm kiếm theo artist, album, tên bài hát
2.1.5.1 search( String searchText)
Khi người dùng nhập kí tự vào searchTextField, hàm này sẽ trả về giá trị Boolean cho biết
có tìm được kết quả nào không và lưu danh sách kết quả (giới hạn 3 phần tử mỗi mục) vào thuộc tính Search.result
2.1.5.2 showSearchResults(SearchResult result)
Hiện kết quả tìm kiếm theo từng mục Artist, Album, Song kèm theo artwork (nếu có) Khi người dụng thay đổi thông tin trên searchTexField, kết quả sẽ thay đổi Khi click vào kết quả tìm kiếm sẽ hiện ra view ArtistMain với các thông tin đang được chọn là kết quả tìm kiếm
2.1.5.3 Animation
Ô tìm kiếm có 2 animation là hiện khung tìm kiếm (searchShowAnimation) và ẩn khung tìm kiếm (searchHideAnimation)
Trang 14Nếu bài hát hiện tại nằm trong size của playlist thì chơi bài tiếp theo
Nếu index không nằm trong size playlist thì kiểm tra có lặp bài hay không
Nếu không lặp thì quay lại bài đầu tiên trong danh sách
Trang 15xii
public static void skip() {
//Nếu nằm bài hát hiện tại nằm trong size của playlist thì chơi bài tiếp theo
//Kiểm tra có lặp bài hát đang chơi, nếu có chơi lại
boolean isPlaying = isPlaying();
Bắt sự kiện khi nhấn nút Previous
Kiểm tra xem timerCouter đã vượt qua bài hát mới hoặc chỉ số bài hát đang chơi hiện tại bằng 0 hay không Nếu có thì chơi lại bài hát, seek(0), ngược lại chơi bài hát tiếp theo
Trang 16Sự kiện click New Playlist
private void newPlaylist()
• Khởi tạo và tạo Hbox Playlist có các sự kiện đi kèm:
• Kéo bài hát hoặc album vào playlist
• Click vào album để truy cập vào Playlist layout
• Press Enter để truy cập Playlist layout
• Hiệu ứng khi hover vào HBox
2.1.7.1 Playing Playlist
Danh sách những bài hát được lấy từ MusicPlayer.getNowPlayingList() và hiển thị ra theo kiểu dữ liệu Song
Trang 17xiv
public class NowPlayingController implements Initializable, SubView {
@FXML private TableView<Song> tableView;
@FXML private TableColumn<Song, Boolean> playingColumn;
@FXML private TableColumn<Song, String> titleColumn;
@FXML private TableColumn<Song, String> artistColumn;
@FXML private TableColumn<Song, String> albumColumn;
@FXML private TableColumn<Song, String> lengthColumn;
@FXML private TableColumn<Song, Integer> playsColumn;
private Song selectedSong;
• Khởi tạo và tạo Hbox Playlist có các sự kiện đi kèm:
• Kéo bài hát hoặc album vào playlist
• Click vào album để truy cập vào Playlist layout
• Press Enter để truy cập Playlist layout
• Hiệu ứng khi hover vào HBox
2.1.7.3 Recently Played, Most Played Playlist & another Playlist
Hàm khởi tạo toàn bộ playlist và đổ dữ liệu vào controller các playlist
private void initializePlaylists()
• Khởi tạo và tạo Hbox Playlist có các sự kiện đi kèm:
• Kéo bài hát hoặc album vào playlist
• Click vào album để truy cập vào Playlist layout
• Press Enter để truy cập Playlist layout
• Hiệu ứng khi hover vào HBox
Trang 18xv
2.1.8 Loop, shuffle, volume của bài hát
2.1.8.1 Lặp bài
//Sự kiện click nút loop thì thêm css màu và chuyển cờ loop ở MusicPlayer
PseudoClass active = PseudoClass.getPseudoClass("active");
loopButton.setOnMouseClicked(x -> {
sideBar.requestFocus();
MusicPlayer.toggleLoop();
loopButton.pseudoClassStateChanged(active, MusicPlayer.isLoopActive()); });
private void createVolumePopup()
Animation khi mở volumePopup
popup.focusedProperty().addListener((x, wasFocused, isFocused) -> {
if (wasFocused && !isFocused) {
volumeHideAnimation.play();
}
});