diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4bc550ec..fa02d039 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -148,6 +148,8 @@ dependencies { val latestAboutLibsRelease = "10.9.1" implementation ("com.mikepenz:aboutlibraries:${latestAboutLibsRelease}") + implementation("com.google.android.flexbox:flexbox:3.0.0") + } hilt { enableAggregatingTask = true diff --git a/app/src/main/java/com/maxrave/simpmusic/adapter/home/chart/TrackChartAdapter.kt b/app/src/main/java/com/maxrave/simpmusic/adapter/home/chart/TrackChartAdapter.kt index eaa988b3..fff577e6 100644 --- a/app/src/main/java/com/maxrave/simpmusic/adapter/home/chart/TrackChartAdapter.kt +++ b/app/src/main/java/com/maxrave/simpmusic/adapter/home/chart/TrackChartAdapter.kt @@ -47,7 +47,7 @@ class TrackChartAdapter( var trackList: ArrayList, val context: Conte artistName = removeTrailingComma(artistName) artistName = removeComma(artistName) binding.tvArtistName.text = artistName - binding.ivArt.load(track.thumbnails.last().url) + binding.ivArt.load(track.thumbnails.lastOrNull()?.url) } } private fun removeTrailingComma(sentence: String): String { diff --git a/app/src/main/java/com/maxrave/simpmusic/data/repository/MainRepository.kt b/app/src/main/java/com/maxrave/simpmusic/data/repository/MainRepository.kt index 3e829a1e..b84fa61f 100644 --- a/app/src/main/java/com/maxrave/simpmusic/data/repository/MainRepository.kt +++ b/app/src/main/java/com/maxrave/simpmusic/data/repository/MainRepository.kt @@ -62,6 +62,7 @@ import com.maxrave.simpmusic.data.parser.search.parseSearchPlaylist import com.maxrave.simpmusic.data.parser.search.parseSearchSong import com.maxrave.simpmusic.data.parser.search.parseSearchVideo import com.maxrave.simpmusic.extension.bestMatchingIndex +import com.maxrave.simpmusic.extension.removeDuplicateWords import com.maxrave.simpmusic.extension.toListTrack import com.maxrave.simpmusic.extension.toLyrics import com.maxrave.simpmusic.extension.toTrack @@ -1116,9 +1117,9 @@ class MainRepository @Inject constructor(private val localDataSource: LocalDataS description = response.videoDetails?.description, youtubeCaptionsUrl = response.captions?.playerCaptionsTracklistRenderer?.captionTracks?.get(0)?.baseUrl?.replace("&fmt=srv3", ""), lengthSeconds = response.videoDetails?.lengthSeconds?.toInt(), - playbackTrackingVideostatsPlaybackUrl = response.playbackTracking?.videostatsPlaybackUrl?.baseUrl, - playbackTrackingAtrUrl = response.playbackTracking?.atrUrl?.baseUrl, - playbackTrackingVideostatsWatchtimeUrl = response.playbackTracking?.videostatsWatchtimeUrl?.baseUrl, + playbackTrackingVideostatsPlaybackUrl = response.playbackTracking?.videostatsPlaybackUrl?.baseUrl?.replace("https://s.youtube.com", "https://music.youtube.com"), + playbackTrackingAtrUrl = response.playbackTracking?.atrUrl?.baseUrl?.replace("https://s.youtube.com", "https://music.youtube.com"), + playbackTrackingVideostatsWatchtimeUrl = response.playbackTracking?.videostatsWatchtimeUrl?.baseUrl?.replace("https://s.youtube.com", "https://music.youtube.com"), ) ) } diff --git a/app/src/main/java/com/maxrave/simpmusic/extension/AllExt.kt b/app/src/main/java/com/maxrave/simpmusic/extension/AllExt.kt index 06ae7c16..cf93c1d1 100644 --- a/app/src/main/java/com/maxrave/simpmusic/extension/AllExt.kt +++ b/app/src/main/java/com/maxrave/simpmusic/extension/AllExt.kt @@ -227,6 +227,14 @@ fun Track.toSongEntity(): SongEntity { ) } +fun String?.removeDuplicateWords(): String { + if (this == null) return "null" + else { + val regex = Regex("\\b(\\w+)\\b\\s*(?=.*\\b\\1\\b)") + return this.replace(regex, "") + } +} + fun SongEntity.toTrack(): Track { val listArtist = mutableListOf() if (this.artistName != null ) { diff --git a/app/src/main/java/com/maxrave/simpmusic/ui/fragment/home/SettingsFragment.kt b/app/src/main/java/com/maxrave/simpmusic/ui/fragment/home/SettingsFragment.kt index b256069c..1acd575a 100644 --- a/app/src/main/java/com/maxrave/simpmusic/ui/fragment/home/SettingsFragment.kt +++ b/app/src/main/java/com/maxrave/simpmusic/ui/fragment/home/SettingsFragment.kt @@ -1,9 +1,11 @@ package com.maxrave.simpmusic.ui.fragment.home +import android.app.usage.StorageStatsManager import android.content.Intent import android.media.audiofx.AudioEffect import android.net.Uri import android.os.Bundle +import android.os.storage.StorageManager import android.util.Log import android.view.LayoutInflater import android.view.View @@ -12,14 +14,17 @@ import android.widget.EditText import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatDelegate +import androidx.core.content.ContextCompat.getSystemService import androidx.core.os.LocaleListCompat import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.media3.common.util.UnstableApi import androidx.navigation.fragment.findNavController import coil.annotation.ExperimentalCoilApi import coil.imageLoader +import com.google.android.flexbox.FlexboxLayout import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.maxrave.simpmusic.R import com.maxrave.simpmusic.common.LIMIT_CACHE_SIZE @@ -37,6 +42,8 @@ import com.maxrave.simpmusic.viewModel.SharedViewModel import com.mikepenz.aboutlibraries.LibsBuilder import dagger.hilt.android.AndroidEntryPoint import dev.chrisbanes.insetter.applyInsetter +import kotlinx.coroutines.launch +import java.io.File import java.text.SimpleDateFormat import java.time.Instant import java.time.LocalDateTime @@ -44,6 +51,7 @@ import java.time.ZoneId import java.time.format.DateTimeFormatter import java.util.Locale + @UnstableApi @AndroidEntryPoint class SettingsFragment : Fragment() { @@ -173,9 +181,11 @@ class SettingsFragment : Fragment() { binding.tvQuality.text = it } viewModel.cacheSize.observe(viewLifecycleOwner) { + drawDataStat() binding.tvPlayerCache.text = getString(R.string.cache_size, bytesToMB(it).toString()) } viewModel.downloadedCacheSize.observe(viewLifecycleOwner) { + drawDataStat() binding.tvDownloadedCache.text = getString(R.string.cache_size, bytesToMB(it).toString()) } binding.tvThumbnailCache.text = getString(R.string.cache_size, if (diskCache?.size != null) { @@ -335,6 +345,7 @@ class SettingsFragment : Fragment() { .setPositiveButton(getString(R.string.clear)) { dialog, _ -> viewModel.clearPlayerCache() viewModel.cacheSize.observe(viewLifecycleOwner) { + drawDataStat() binding.tvPlayerCache.text = getString(R.string.cache_size, bytesToMB(it).toString()) } dialog.dismiss() @@ -497,6 +508,7 @@ class SettingsFragment : Fragment() { viewModel.clearDownloadedCache() viewModel.downloadedCacheSize.observe(viewLifecycleOwner) { binding.tvPlayerCache.text = getString(R.string.cache_size, bytesToMB(it).toString()) + drawDataStat() } dialog.dismiss() } @@ -632,6 +644,50 @@ class SettingsFragment : Fragment() { LibsBuilder() .start(requireContext()) } + + + } + private fun browseFiles(dir: File): Long { + var dirSize: Long = 0 + if (!dir.listFiles().isNullOrEmpty()) { + for (f in dir.listFiles()!!) { + dirSize += f.length() + Log.d("STORAGE_TAG", dir.absolutePath + "/" + f.name + " uses " + f.length() + " bytes") + if (f.isDirectory) { + dirSize += browseFiles(f) + } + } + } + Log.d("STORAGE_TAG", dir.absolutePath + " uses " + dirSize + " bytes") + return dirSize + } + private fun drawDataStat() { + val mStorageStatsManager = getSystemService(requireContext(), StorageStatsManager::class.java) + if (mStorageStatsManager != null) { + lifecycleScope.launch { + val totalByte = mStorageStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT) + Log.w("Total", bytesToMB(totalByte).toString()) + val freeSpace = mStorageStatsManager.getFreeBytes(StorageManager.UUID_DEFAULT) + Log.w("Free", bytesToMB(freeSpace).toString()) + val usedSpace = totalByte - freeSpace + Log.w("Used", bytesToMB(usedSpace).toString()) + val simpMusicSize = browseFiles(requireContext().filesDir) + Log.w("SimpMusic", bytesToMB(simpMusicSize).toString()) + val otherApp = simpMusicSize.let { usedSpace.minus(it) } + Log.w("Other", bytesToMB(otherApp).toString()) + val databaseSize = simpMusicSize - viewModel.playerCache.cacheSpace - viewModel.downloadCache.cacheSpace + Log.w("Database", databaseSize.toString()) + Log.w("Player", viewModel.playerCache.cacheSpace.toString()) + Log.w("Download", viewModel.downloadCache.cacheSpace.toString()) + if (totalByte == freeSpace + otherApp + databaseSize + viewModel.playerCache.cacheSpace + viewModel.downloadCache.cacheSpace) { + (binding.flexBox.getChildAt(0).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = otherApp.toFloat().div(totalByte.toFloat()) + (binding.flexBox.getChildAt(1).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = viewModel.downloadCache.cacheSpace.toFloat().div(totalByte.toFloat()) + (binding.flexBox.getChildAt(2).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = viewModel.playerCache.cacheSpace.toFloat().div(totalByte.toFloat()) + (binding.flexBox.getChildAt(3).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = databaseSize.toFloat().div(totalByte.toFloat()) + (binding.flexBox.getChildAt(4).layoutParams as FlexboxLayout.LayoutParams).flexBasisPercent = freeSpace.toFloat().div(totalByte.toFloat()) + } + } + } } private fun bytesToMB(bytes: Long): Long { diff --git a/app/src/main/java/com/maxrave/simpmusic/ui/fragment/other/PlaylistFragment.kt b/app/src/main/java/com/maxrave/simpmusic/ui/fragment/other/PlaylistFragment.kt index 3defa18f..b169c25f 100644 --- a/app/src/main/java/com/maxrave/simpmusic/ui/fragment/other/PlaylistFragment.kt +++ b/app/src/main/java/com/maxrave/simpmusic/ui/fragment/other/PlaylistFragment.kt @@ -602,6 +602,7 @@ class PlaylistFragment: Fragment() { } collapsingToolbarLayout.title = it?.title tvTitle.text = it?.title + tvTitle.isSelected = true tvPlaylistAuthor.text = it?.author?.name if (it?.year != "") { tvYearAndCategory.text = requireContext().getString(R.string.year_and_category, it?.year.toString(), "Playlist") @@ -688,6 +689,7 @@ class PlaylistFragment: Fragment() { } collapsingToolbarLayout.title = it?.title tvTitle.text = it?.title + tvTitle.isSelected = true tvPlaylistAuthor.text = it?.author?.name if (it?.year != "") { tvYearAndCategory.text = requireContext().getString(R.string.year_and_category, it?.year.toString(), "Playlist") @@ -748,6 +750,7 @@ class PlaylistFragment: Fragment() { } collapsingToolbarLayout.title = it?.title tvTitle.text = it?.title + tvTitle.isSelected = true tvPlaylistAuthor.text = it?.author?.name if (it?.year != "") { tvYearAndCategory.text = requireContext().getString(R.string.year_and_category, it?.year.toString(), "Playlist") @@ -838,6 +841,7 @@ class PlaylistFragment: Fragment() { } collapsingToolbarLayout.title = playlistEntity.title tvTitle.text = playlistEntity.title + tvTitle.isSelected = true tvPlaylistAuthor.text = playlistEntity.author tvYearAndCategory.text = requireContext().getString(R.string.year_and_category, playlistEntity.year.toString(), "Playlist") tvTrackCountAndDuration.text = requireContext().getString(R.string.album_length, playlistEntity.trackCount.toString(), diff --git a/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt b/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt index ff5c7c80..8c3daff4 100644 --- a/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt +++ b/app/src/main/java/com/maxrave/simpmusic/viewModel/SettingsViewModel.kt @@ -49,8 +49,8 @@ class SettingsViewModel @Inject constructor( private var mainRepository: MainRepository, private var database: MusicDatabase, private var databaseDao: DatabaseDao, - @PlayerCache private val playerCache: SimpleCache, - @DownloadCache private val downloadCache: SimpleCache, + @PlayerCache val playerCache: SimpleCache, + @DownloadCache val downloadCache: SimpleCache, ) : AndroidViewModel(application) { @Inject diff --git a/app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt b/app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt index cedf1d43..06ea1b48 100644 --- a/app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt +++ b/app/src/main/java/com/maxrave/simpmusic/viewModel/SharedViewModel.kt @@ -1021,16 +1021,21 @@ class SharedViewModel @Inject constructor(private var dataStoreManager: DataStor viewModelScope.launch { if (dataStoreManager.lyricsProvider.first() == DataStoreManager.MUSIXMATCH) { mainRepository.getSongById(videoId).first().let { song -> + val artist = if (song?.artistName?.firstOrNull() != null && song.artistName.firstOrNull()?.contains("Various Artists") == false) { + song.artistName.firstOrNull() + } else { + simpleMediaServiceHandler?.nowPlaying?.first()?.mediaMetadata?.artist ?: "" + } song?.let { if (song.downloadState == DownloadState.STATE_DOWNLOADED) { getSavedLyrics( song.toTrack().copy( durationSeconds = duration - ), "${song.title} ${song.artistName?.firstOrNull()}" + ), "${song.title} $artist" ) } else { mainRepository.getLyricsData( - "${song.title} ${song.artistName?.firstOrNull()}", + "${song.title} $artist", duration ).collect { response -> _lyrics.value = response.second @@ -1055,7 +1060,7 @@ class SharedViewModel @Inject constructor(private var dataStoreManager: DataStor getSavedLyrics( song.toTrack().copy( durationSeconds = duration - ), "${song.title} ${song.artistName?.firstOrNull()}" + ), "${song.title} $artist" ) } } @@ -1084,7 +1089,7 @@ class SharedViewModel @Inject constructor(private var dataStoreManager: DataStor getSavedLyrics( song.toTrack().copy( durationSeconds = duration - ), "${song.title} ${song.artistName?.firstOrNull()}" + ), "${song.title} ${song.artistName?.firstOrNull() ?: simpleMediaServiceHandler?.nowPlaying?.first()?.mediaMetadata?.artist ?: ""}" ) } } diff --git a/app/src/main/res/layout/fragment_artist.xml b/app/src/main/res/layout/fragment_artist.xml index c86f2434..38799d64 100644 --- a/app/src/main/res/layout/fragment_artist.xml +++ b/app/src/main/res/layout/fragment_artist.xml @@ -379,7 +379,7 @@ + android:layout_height="180sp"> diff --git a/app/src/main/res/layout/fragment_playlist.xml b/app/src/main/res/layout/fragment_playlist.xml index 9be3c011..ab7835e7 100644 --- a/app/src/main/res/layout/fragment_playlist.xml +++ b/app/src/main/res/layout/fragment_playlist.xml @@ -71,6 +71,12 @@ android:id="@+id/tvTitle" style="@style/album_name" android:text="Playlist" + android:singleLine="true" + android:ellipsize="marquee" + android:marqueeRepeatLimit="marquee_forever" + android:focusable="true" + android:focusableInTouchMode="true" + android:scrollHorizontally="true" android:layout_width="wrap_content" android:layout_height="wrap_content"> diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index 5b2a25dc..9d38ffe4 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -772,6 +772,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ĐANG PHÁT Ngôn ngữ Bạn đang muốn nghe gì? - - %d bài hát - %d bài hát - Bài hát Đĩa nhạc Đĩa đơn @@ -146,8 +142,8 @@ Gửi Báo cáo Xoá bài hát này khỏi danh sách phát - Đăng nhập vào YouTube Đăng nhập + Đăng nhập vào YouTube Đăng nhập để cá nhân hoá nguồn dữ liệu Đăng nhập thành công Đăng xuất khỏi YouTube @@ -175,7 +171,7 @@ Lưu chế độ trộn và phát lại Bỏ qua im lặng Bỏ qua phần không có nhạc - Quá thời gian, kiểm tra kết nối internet + Quá thời gian, kiểm qua kết nối internet Lưu phiên phát lại cuối cùng Lưu bài hát đang phát và danh sách chờ cuối cùng Phiên bản mới có sẵn @@ -239,11 +235,38 @@ Đăng nhập để tải danh sách phát YouTube của bạn SimpMusic sẽ tự động tạo một danh sách phát trên YouTube Music. Bạn có chắc chắn? Đang đồng bộ - Huỷ đồng bộ danh sách phát này? Điều này sẽ không xoá danh sách phát này trên YouTube Music + "Huỷ đồng bộ danh sách phát này? Điều này sẽ không xoá danh sách phát này trên YouTube Music" Đang huỷ đồng bộ Đã thêm vào danh sách phát YouTube Đã xoá khỏi danh sách phát YouTube Cập nhật danh sách phát từ YouTube Music Sao lưu thành công Sao lưu thất bại - \ No newline at end of file + Musixmatch + Nguồn cung cấp lời bài hát chính + Đăng nhập vào Musixmatch + Chỉ hỗ trợ đăng nhập bằng email và mật khẩu + API dịch của Musixmatch chỉ hoạt động với người dùng đã đăng nhập. SimpMusic sử dụng một vài mẹo để tìm ra các API đã được Musixmatch ẩn. Xem thêm thông tin, đi đến https://github.com/maxrave-dev/SimpMusic + Sử dụng hệ thống dịch của Musixmatch + Bật dịch bài hát sử dụng Musixmatch. Yêu cầu đăng nhập + Ngôn ngữ dịch + Theo ngôn ngữ của ứng dụng + Email + Mật khẩu + Hãy nhập email và mật khẩu của bạn + Đăng xuất tài khoản Musixmatch + Nhập mã ngôn ngữ (Ví dụ: vi) (2 kí tự). Nếu bạn muốn để theo ngôn ngữ chính của SimpMusic, hãy để trống + Mã ngôn ngữ không hợp lệ + Lời bài hát được cung cấp bởi YouTube + Giới hạn cache của trình phát nhạc + Không giới hạn + Thư viện bên thứ ba + Mô tả và giấy phép + Tác giả + Ứng dụng khác + Cơ sở dữ liệu của ứng dụng + Còn trống + + %d bài hát + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2a1b588b..1bfec5db 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -264,6 +264,9 @@ Third party libraries Description and licenses Author + Other app + App database + Free space %d song %d songs diff --git a/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/YouTube.kt b/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/YouTube.kt index b845266f..a4747e35 100644 --- a/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/YouTube.kt +++ b/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/YouTube.kt @@ -578,28 +578,39 @@ object YouTube { } } suspend fun initPlayback(playbackUrl: String, atrUrl: String, watchtimeUrl: String): Result { + println("playbackUrl $playbackUrl") + println("atrUrl $atrUrl") + println("watchtimeUrl $watchtimeUrl") return runCatching { val cpn = (1..16).map { "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"[Random.Default.nextInt(0, 64)] }.joinToString("") ytMusic.initPlayback(playbackUrl, cpn).status.value.let { status -> if (status == 204) { println("playback done") - delay(5000) - ytMusic.initPlayback(atrUrl, cpn).status.value.let { atr -> - if (atr == 204) { - println("atr done") - delay(500) - ytMusic.initPlayback(watchtimeUrl, cpn).status.value.let { watchtime -> - if (watchtime == 204) { - println("watchtime done") - return@runCatching 204 + ytMusic.initPlayback(watchtimeUrl, cpn, mapOf("st" to "0", "et" to (Math.round(Random.nextFloat()*100)/100 + 2f).toString())).status.value.let { firstWatchTime -> + if (firstWatchTime == 204) { + println("first watchtime done") + delay(5000) + ytMusic.atr(atrUrl, cpn).status.value.let { atr -> + if (atr == 204) { + println("atr done") + delay(500) + ytMusic.initPlayback(watchtimeUrl, cpn, mapOf("st" to "0,5.54", "et" to "5.54,${(Math.round(Random.nextFloat()*100)/100 + 12f)}")).status.value.let { watchtime -> + if (watchtime == 204) { + println("watchtime done") + return@runCatching 204 + } + else { + return@runCatching watchtime + } + } } else { - return@runCatching watchtime + return@runCatching atr } } } else { - return@runCatching atr + return@runCatching firstWatchTime } } } diff --git a/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/Ytmusic.kt b/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/Ytmusic.kt index 71815422..79eef977 100644 --- a/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/Ytmusic.kt +++ b/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/Ytmusic.kt @@ -634,12 +634,24 @@ class Ytmusic { } } - suspend fun initPlayback(url: String, cpn: String) + suspend fun initPlayback(url: String, cpn: String, customParams: Map? = null) = httpClient.get(url) { ytClient(YouTubeClient.ANDROID_MUSIC, true) parameter("ver", "2") parameter("c", "ANDROID_MUSIC") parameter("cpn", cpn) + customParams?.forEach { (key, value) -> + parameter(key, value) + } + } + + suspend fun atr(url: String, cpn: String, customParams: Map? = null) = httpClient.post(url) { + ytClient(YouTubeClient.ANDROID_MUSIC, true) + parameter("c", "ANDROID_MUSIC") + parameter("cpn", cpn) + customParams?.forEach { (key, value) -> + parameter(key, value) + } } diff --git a/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/test/main.kt b/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/test/main.kt index 2d0cd90e..dc39bf5b 100644 --- a/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/test/main.kt +++ b/kotlinYtmusicScraper/src/main/java/com/maxrave/kotlinytmusicscraper/test/main.kt @@ -1,6 +1,7 @@ package com.maxrave.kotlinytmusicscraper.test import com.google.gson.annotations.SerializedName +import com.maxrave.kotlinytmusicscraper.YouTube import com.maxrave.kotlinytmusicscraper.models.GridRenderer import com.maxrave.kotlinytmusicscraper.models.MusicResponsiveListItemRenderer import com.maxrave.kotlinytmusicscraper.models.MusicTwoRowItemRenderer @@ -12,6 +13,11 @@ import kotlinx.coroutines.runBlocking fun main() { runBlocking { + YouTube.player("Hi1Hj4VlqP8").onSuccess { + println(it) + }.onFailure { + it.printStackTrace() + } // YouTube.spotifyCookie = // "sp_t=a910acb941e990e349d79e8170f2dafe; _scid=e96b060c-30fc-4c59-9e44-25f376482edd; _ga=GA1.2.2112854199.1671017821; sp_adid=95e621d6-b86c-4ce5-bed4-6b03ab65155b; _ga_ZWG1NSHWD8=GS1.1.1671017821.1.0.1671017823.0.0.0; sp_dc=AQAYI79gjZIRlNjJUDXJLIq1yw5Nb_E85T55B8jgHOVWOseGrnhlVuEKRziSRV1XA8Ca2d7bx7RAQ-6hjGLWNlsxHrZ6DP6Jmn_Joz-6djb05evRb31kKFGrTXhRzFBRMr5MePVo2pujxkVtOjCZp_qNP1J3ryQ; sp_key=595700a0-212b-4ce5-a497-0f7eea005f35; OptanonAlertBoxClosed=2022-12-27T15:05:03.114Z; sp_m=vn-vi; sp_landing=https%3A%2F%2Fopen.spotify.com%2Ftrack%2F1GPRHgVXzRfzoc44HEZZQI%3Fsp_cid%3Da910acb941e990e349d79e8170f2dafe%26device%3Ddesktop; OptanonConsent=isIABGlobal=false&datestamp=Sat+Sep+30+2023+22%3A30%3A16+GMT%2B0700+(Indochina+Time)&version=6.26.0&hosts=&landingPath=NotLandingPage&groups=s00%3A1%2Cf00%3A1%2Cm00%3A1%2Ct00%3A1%2Ci00%3A1%2Cf11%3A0&AwaitingReconsent=false&geolocation=VN%3BSG" // YouTube.cookie =