mirror of
https://github.com/Shabinder/SpotiFlyer.git
synced 2024-11-25 02:14:32 +01:00
YT Image URL Schema Change from HI_RES->HQ-Default
This commit is contained in:
parent
c0e3a35898
commit
a5793cc72c
@ -6,6 +6,7 @@
|
|||||||
<w>emoji</w>
|
<w>emoji</w>
|
||||||
<w>ffmpeg</w>
|
<w>ffmpeg</w>
|
||||||
<w>flyer</w>
|
<w>flyer</w>
|
||||||
|
<w>hqdefault</w>
|
||||||
<w>insta</w>
|
<w>insta</w>
|
||||||
<w>instagram</w>
|
<w>instagram</w>
|
||||||
<w>jetbrains</w>
|
<w>jetbrains</w>
|
||||||
|
@ -48,8 +48,8 @@ object YTDownloadHelper {
|
|||||||
|
|
||||||
val downloadObject = DownloadObject(
|
val downloadObject = DownloadObject(
|
||||||
trackDetails = it,
|
trackDetails = it,
|
||||||
ytVideoId = "https://i.ytimg.com/vi/${it.albumArt.absolutePath.substringAfterLast("/")
|
ytVideoId = it.albumArt.absolutePath.substringAfterLast("/")
|
||||||
.substringBeforeLast(".")}/maxresdefault.jpg",
|
.substringBeforeLast("."),
|
||||||
outputFile = outputFile
|
outputFile = outputFile
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ class DownloadRecordAdapter: ListAdapter<DownloadRecord,DownloadRecordAdapter.Vi
|
|||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val item = getItem(position)
|
val item = getItem(position)
|
||||||
adapterScope.launch {
|
adapterScope.launch {
|
||||||
bindImage(holder.binding.coverUrl,item.coverUrl)
|
bindImage(holder.binding.coverUrl,item.coverUrl,null)
|
||||||
}
|
}
|
||||||
holder.binding.itemName.text = item.name
|
holder.binding.itemName.text = item.name
|
||||||
holder.binding.totalItems.text = "Tracks: ${item.totalFiles}"
|
holder.binding.totalItems.text = "Tracks: ${item.totalFiles}"
|
||||||
|
@ -20,19 +20,22 @@ package com.shabinder.spotiflyer.recyclerView
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import com.shabinder.spotiflyer.R
|
||||||
import com.shabinder.spotiflyer.databinding.TrackListItemBinding
|
import com.shabinder.spotiflyer.databinding.TrackListItemBinding
|
||||||
|
import com.shabinder.spotiflyer.downloadHelper.YTDownloadHelper
|
||||||
|
import com.shabinder.spotiflyer.models.DownloadStatus
|
||||||
import com.shabinder.spotiflyer.models.Source
|
import com.shabinder.spotiflyer.models.Source
|
||||||
import com.shabinder.spotiflyer.models.TrackDetails
|
import com.shabinder.spotiflyer.models.TrackDetails
|
||||||
|
import com.shabinder.spotiflyer.ui.youtube.YoutubeViewModel
|
||||||
|
import com.shabinder.spotiflyer.utils.Provider
|
||||||
import com.shabinder.spotiflyer.utils.bindImage
|
import com.shabinder.spotiflyer.utils.bindImage
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import com.shabinder.spotiflyer.utils.rotateAnim
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class YoutubeTrackListAdapter: ListAdapter<TrackDetails,SpotifyTrackListAdapter.ViewHolder>(YouTubeTrackDiffCallback()) {
|
class YoutubeTrackListAdapter(private val youtubeViewModel :YoutubeViewModel): ListAdapter<TrackDetails,SpotifyTrackListAdapter.ViewHolder>(YouTubeTrackDiffCallback()) {
|
||||||
|
|
||||||
private val adapterScope = CoroutineScope(Dispatchers.Default)
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(
|
override fun onCreateViewHolder(
|
||||||
parent: ViewGroup,
|
parent: ViewGroup,
|
||||||
@ -48,24 +51,50 @@ class YoutubeTrackListAdapter: ListAdapter<TrackDetails,SpotifyTrackListAdapter.
|
|||||||
val item = getItem(position)
|
val item = getItem(position)
|
||||||
if(itemCount == 1){
|
if(itemCount == 1){
|
||||||
holder.binding.imageUrl.visibility = View.GONE}else{
|
holder.binding.imageUrl.visibility = View.GONE}else{
|
||||||
adapterScope.launch {
|
youtubeViewModel.uiScope.launch {
|
||||||
bindImage(holder.binding.imageUrl,
|
bindImage(holder.binding.imageUrl,
|
||||||
"https://i.ytimg.com/vi/${item.albumArt.absolutePath.substringAfterLast("/")
|
"https://i.ytimg.com/vi/${item.albumArt.absolutePath.substringAfterLast("/")
|
||||||
.substringBeforeLast(".")}/maxresdefault.jpg"
|
.substringBeforeLast(".")}/hqdefault.jpg"
|
||||||
,
|
,
|
||||||
Source.YouTube
|
Source.YouTube
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when (item.downloaded) {
|
||||||
|
DownloadStatus.Downloaded -> {
|
||||||
|
holder.binding.btnDownload.setImageResource(R.drawable.ic_tick)
|
||||||
|
holder.binding.btnDownload.clearAnimation()
|
||||||
|
}
|
||||||
|
DownloadStatus.Downloading -> {
|
||||||
|
holder.binding.btnDownload.setImageResource(R.drawable.ic_refresh)
|
||||||
|
rotateAnim(holder.binding.btnDownload)
|
||||||
|
}
|
||||||
|
DownloadStatus.NotDownloaded -> {
|
||||||
|
holder.binding.btnDownload.setImageResource(R.drawable.ic_arrow)
|
||||||
|
holder.binding.btnDownload.clearAnimation()
|
||||||
|
holder.binding.btnDownload.setOnClickListener{
|
||||||
|
Toast.makeText(Provider.activity,"Processing!", Toast.LENGTH_SHORT).show()
|
||||||
|
holder.binding.btnDownload.setImageResource(R.drawable.ic_refresh)
|
||||||
|
rotateAnim(it)
|
||||||
|
item.downloaded = DownloadStatus.Downloading
|
||||||
|
youtubeViewModel.uiScope.launch {
|
||||||
|
val itemList = mutableListOf<TrackDetails>()
|
||||||
|
itemList.add(item)
|
||||||
|
YTDownloadHelper.downloadYTTracks(
|
||||||
|
youtubeViewModel.folderType,
|
||||||
|
youtubeViewModel.subFolder,
|
||||||
|
itemList
|
||||||
|
)
|
||||||
|
}
|
||||||
|
notifyItemChanged(position)//start showing anim!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
holder.binding.trackName.text = "${if(item.title.length > 17){"${item.title.subSequence(0,16)}..."}else{item.title}}"
|
holder.binding.trackName.text = "${if(item.title.length > 17){"${item.title.subSequence(0,16)}..."}else{item.title}}"
|
||||||
holder.binding.artist.text = "${item.artists.get(0)}..."
|
holder.binding.artist.text = "${item.artists.get(0)}..."
|
||||||
holder.binding.duration.text = "${item.durationSec/60} minutes, ${item.durationSec%60} sec"
|
holder.binding.duration.text = "${item.durationSec/60} minutes, ${item.durationSec%60} sec"
|
||||||
holder.binding.btnDownload.setOnClickListener{
|
|
||||||
adapterScope.launch {
|
|
||||||
// YTDownloadHelper.downloadFile(null,"YT_Downloads",item,format)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class YouTubeTrackDiffCallback: DiffUtil.ItemCallback<TrackDetails>(){
|
class YouTubeTrackDiffCallback: DiffUtil.ItemCallback<TrackDetails>(){
|
||||||
|
@ -17,7 +17,12 @@
|
|||||||
|
|
||||||
package com.shabinder.spotiflyer.ui.youtube
|
package com.shabinder.spotiflyer.ui.youtube
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@ -52,6 +57,8 @@ class YoutubeFragment : Fragment() {
|
|||||||
private lateinit var adapter : YoutubeTrackListAdapter
|
private lateinit var adapter : YoutubeTrackListAdapter
|
||||||
private val sampleDomain1 = "youtube.com"
|
private val sampleDomain1 = "youtube.com"
|
||||||
private val sampleDomain2 = "youtu.be"
|
private val sampleDomain2 = "youtu.be"
|
||||||
|
private var intentFilter: IntentFilter? = null
|
||||||
|
private var updateUIReceiver: BroadcastReceiver? = null
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
@ -60,10 +67,11 @@ class YoutubeFragment : Fragment() {
|
|||||||
binding = DataBindingUtil.inflate(inflater,R.layout.youtube_fragment,container,false)
|
binding = DataBindingUtil.inflate(inflater,R.layout.youtube_fragment,container,false)
|
||||||
youtubeViewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java)
|
youtubeViewModel = ViewModelProvider(this).get(YoutubeViewModel::class.java)
|
||||||
sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java)
|
sharedViewModel = ViewModelProvider(this.requireActivity()).get(SharedViewModel::class.java)
|
||||||
adapter = YoutubeTrackListAdapter()
|
adapter = YoutubeTrackListAdapter(youtubeViewModel)
|
||||||
binding.trackList.adapter = adapter
|
binding.trackList.adapter = adapter
|
||||||
|
|
||||||
initializeLiveDataObservers()
|
initializeLiveDataObservers()
|
||||||
|
initializeBroadcast()
|
||||||
|
|
||||||
val args = YoutubeFragmentArgs.fromBundle(requireArguments())
|
val args = YoutubeFragmentArgs.fromBundle(requireArguments())
|
||||||
val link = args.link
|
val link = args.link
|
||||||
@ -89,6 +97,10 @@ class YoutubeFragment : Fragment() {
|
|||||||
youtubeViewModel.getYTTrack(searchId,ytDownloader)
|
youtubeViewModel.getYTTrack(searchId,ytDownloader)
|
||||||
}else{showToast("Your Youtube Link is not of a Video!!")}
|
}else{showToast("Your Youtube Link is not of a Video!!")}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Download All Tracks
|
||||||
|
* */
|
||||||
binding.btnDownloadAll.setOnClickListener {
|
binding.btnDownloadAll.setOnClickListener {
|
||||||
binding.btnDownloadAll.visibility = View.GONE
|
binding.btnDownloadAll.visibility = View.GONE
|
||||||
binding.downloadingFab.visibility = View.VISIBLE
|
binding.downloadingFab.visibility = View.VISIBLE
|
||||||
@ -105,7 +117,7 @@ class YoutubeFragment : Fragment() {
|
|||||||
sharedViewModel.uiScope.launch(Dispatchers.Default){
|
sharedViewModel.uiScope.launch(Dispatchers.Default){
|
||||||
val urlList = arrayListOf<String>()
|
val urlList = arrayListOf<String>()
|
||||||
youtubeViewModel.ytTrackList.value?.forEach { urlList.add("https://i.ytimg.com/vi/${it.albumArt.absolutePath.substringAfterLast("/")
|
youtubeViewModel.ytTrackList.value?.forEach { urlList.add("https://i.ytimg.com/vi/${it.albumArt.absolutePath.substringAfterLast("/")
|
||||||
.substringBeforeLast(".")}/maxresdefault.jpg")}
|
.substringBeforeLast(".")}/hqdefault.jpg")}
|
||||||
//Appending Source
|
//Appending Source
|
||||||
urlList.add("youtube")
|
urlList.add("youtube")
|
||||||
loadAllImages(
|
loadAllImages(
|
||||||
@ -122,7 +134,56 @@ class YoutubeFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
initializeBroadcast()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initializeBroadcast() {
|
||||||
|
intentFilter = IntentFilter()
|
||||||
|
intentFilter?.addAction("track_download_completed")
|
||||||
|
|
||||||
|
updateUIReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
//UI update here
|
||||||
|
if (intent != null){
|
||||||
|
val trackDetails = intent.getParcelableExtra<TrackDetails?>("track")
|
||||||
|
trackDetails?.let {
|
||||||
|
val position: Int = youtubeViewModel.ytTrackList.value?.map { it.title }?.indexOf(trackDetails.title) ?: -1
|
||||||
|
Log.i("Track","Download Completed Intent :$position")
|
||||||
|
if(position != -1) {
|
||||||
|
val track = youtubeViewModel.ytTrackList.value?.get(position)
|
||||||
|
track?.let{
|
||||||
|
it.downloaded = DownloadStatus.Downloaded
|
||||||
|
youtubeViewModel.ytTrackList.value?.set(position, it)
|
||||||
|
adapter.notifyItemChanged(position)
|
||||||
|
checkIfAllDownloaded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requireActivity().registerReceiver(updateUIReceiver, intentFilter)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
requireActivity().unregisterReceiver(updateUIReceiver)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkIfAllDownloaded() {
|
||||||
|
if(!youtubeViewModel.ytTrackList.value!!.any { it.downloaded != DownloadStatus.Downloaded }){
|
||||||
|
//All Tracks Downloaded
|
||||||
|
binding.btnDownloadAll.visibility = View.GONE
|
||||||
|
binding.downloadingFab.apply{
|
||||||
|
setImageResource(R.drawable.ic_tick)
|
||||||
|
visibility = View.VISIBLE
|
||||||
|
clearAnimation()
|
||||||
|
keepScreenOn = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private fun initializeLiveDataObservers() {
|
private fun initializeLiveDataObservers() {
|
||||||
/**
|
/**
|
||||||
* CoverUrl Binding Observer!
|
* CoverUrl Binding Observer!
|
||||||
|
@ -32,6 +32,7 @@ import com.shabinder.spotiflyer.models.Source
|
|||||||
import com.shabinder.spotiflyer.models.TrackDetails
|
import com.shabinder.spotiflyer.models.TrackDetails
|
||||||
import com.shabinder.spotiflyer.utils.Provider
|
import com.shabinder.spotiflyer.utils.Provider
|
||||||
import com.shabinder.spotiflyer.utils.Provider.defaultDir
|
import com.shabinder.spotiflyer.utils.Provider.defaultDir
|
||||||
|
import com.shabinder.spotiflyer.utils.Provider.showToast
|
||||||
import com.shabinder.spotiflyer.utils.finalOutputDir
|
import com.shabinder.spotiflyer.utils.finalOutputDir
|
||||||
import com.shabinder.spotiflyer.utils.removeIllegalChars
|
import com.shabinder.spotiflyer.utils.removeIllegalChars
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
@ -41,10 +42,11 @@ class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* YT Album Art Schema
|
* YT Album Art Schema
|
||||||
* Normal Url: https://i.ytimg.com/vi/$searchId/maxresdefault.jpg"
|
* HI-RES Url: https://i.ytimg.com/vi/$searchId/maxresdefault.jpg"
|
||||||
|
* Normal Url: https://i.ytimg.com/vi/$searchId/hqdefault.jpg"
|
||||||
* */
|
* */
|
||||||
|
|
||||||
val ytTrackList = MutableLiveData<List<TrackDetails>>()
|
val ytTrackList = MutableLiveData<MutableList<TrackDetails>>()
|
||||||
val format = MutableLiveData<Format>()
|
val format = MutableLiveData<Format>()
|
||||||
private val loading = "Loading"
|
private val loading = "Loading"
|
||||||
var title = MutableLiveData<String>().apply { value = "\"Loading!\"" }
|
var title = MutableLiveData<String>().apply { value = "\"Loading!\"" }
|
||||||
@ -56,6 +58,7 @@ class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
|
|
||||||
|
|
||||||
fun getYTPlaylist(searchId:String, ytDownloader:YoutubeDownloader){
|
fun getYTPlaylist(searchId:String, ytDownloader:YoutubeDownloader){
|
||||||
|
try{
|
||||||
uiScope.launch(Dispatchers.IO) {
|
uiScope.launch(Dispatchers.IO) {
|
||||||
Log.i("YT Playlist",searchId)
|
Log.i("YT Playlist",searchId)
|
||||||
val playlist = ytDownloader.getPlaylist(searchId)
|
val playlist = ytDownloader.getPlaylist(searchId)
|
||||||
@ -63,7 +66,7 @@ class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
val name = playlistDetails.title()
|
val name = playlistDetails.title()
|
||||||
subFolder = removeIllegalChars(name).toString()
|
subFolder = removeIllegalChars(name).toString()
|
||||||
val videos = playlist.videos()
|
val videos = playlist.videos()
|
||||||
coverUrl.postValue("https://i.ytimg.com/vi/${videos.firstOrNull()?.videoId()}/maxresdefault.jpg")
|
coverUrl.postValue("https://i.ytimg.com/vi/${videos.firstOrNull()?.videoId()}/hqdefault.jpg")
|
||||||
title.postValue(
|
title.postValue(
|
||||||
if(name.length > 17){"${name.subSequence(0,16)}..."}else{name}
|
if(name.length > 17){"${name.subSequence(0,16)}..."}else{name}
|
||||||
)
|
)
|
||||||
@ -74,39 +77,54 @@ class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
durationSec = it.lengthSeconds(),
|
durationSec = it.lengthSeconds(),
|
||||||
albumArt = File(
|
albumArt = File(
|
||||||
Environment.getExternalStorageDirectory(),
|
Environment.getExternalStorageDirectory(),
|
||||||
defaultDir +".Images/" + it.videoId() + ".jpeg"
|
defaultDir + ".Images/" + it.videoId() + ".jpeg"
|
||||||
),
|
),
|
||||||
source = Source.YouTube,
|
source = Source.YouTube,
|
||||||
downloaded = if(File(finalOutputDir(itemName = removeIllegalChars(name),type = folderType,subFolder = subFolder)).exists())
|
downloaded = if (File(
|
||||||
DownloadStatus.Downloaded
|
finalOutputDir(
|
||||||
else DownloadStatus.NotDownloaded
|
itemName = it.title(),
|
||||||
|
type = folderType,
|
||||||
|
subFolder = subFolder
|
||||||
)
|
)
|
||||||
})
|
).exists()
|
||||||
|
)
|
||||||
|
DownloadStatus.Downloaded
|
||||||
|
else {
|
||||||
|
DownloadStatus.NotDownloaded
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}.toMutableList())
|
||||||
|
|
||||||
withContext(Dispatchers.IO){
|
withContext(Dispatchers.IO){
|
||||||
databaseDAO.insert(DownloadRecord(
|
databaseDAO.insert(DownloadRecord(
|
||||||
type = "PlayList",
|
type = "PlayList",
|
||||||
name = if(name.length > 17){"${name.subSequence(0,16)}..."}else{name},
|
name = if(name.length > 17){"${name.subSequence(0,16)}..."}else{name},
|
||||||
link = "https://www.youtube.com/playlist?list=$searchId",
|
link = "https://www.youtube.com/playlist?list=$searchId",
|
||||||
coverUrl = "https://i.ytimg.com/vi/${videos.firstOrNull()?.videoId()}/maxresdefault.jpg",
|
coverUrl = "https://i.ytimg.com/vi/${videos.firstOrNull()?.videoId()}/hqdefault.jpg",
|
||||||
totalFiles = videos.size,
|
totalFiles = videos.size,
|
||||||
directory = finalOutputDir(itemName = removeIllegalChars(name),type = folderType,subFolder = subFolder),
|
directory = finalOutputDir(itemName = removeIllegalChars(name),type = folderType,subFolder = subFolder),
|
||||||
downloaded = File(finalOutputDir(itemName = removeIllegalChars(name),type = folderType,subFolder = subFolder)).exists()
|
downloaded = File(finalOutputDir(itemName = removeIllegalChars(name),type = folderType,subFolder = subFolder)).exists()
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}catch (e:com.github.kiulian.downloader.YoutubeException.BadPageException){
|
||||||
|
showToast("An Error Occurred While Processing!")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
fun getYTTrack(searchId:String, ytDownloader:YoutubeDownloader) {
|
fun getYTTrack(searchId:String, ytDownloader:YoutubeDownloader) {
|
||||||
|
try{
|
||||||
uiScope.launch(Dispatchers.IO) {
|
uiScope.launch(Dispatchers.IO) {
|
||||||
Log.i("YT Video",searchId)
|
Log.i("YT Video",searchId)
|
||||||
val video = ytDownloader.getVideo(searchId)
|
val video = ytDownloader.getVideo(searchId)
|
||||||
coverUrl.postValue("https://i.ytimg.com/vi/$searchId/maxresdefault.jpg")
|
coverUrl.postValue("https://i.ytimg.com/vi/$searchId/hqdefault.jpg")
|
||||||
val detail = video?.details()
|
val detail = video?.details()
|
||||||
val name = detail?.title()?.replace(detail.author()!!.toUpperCase(),"",true) ?: detail?.title() ?: ""
|
val name = detail?.title()?.replace(detail.author()!!.toUpperCase(),"",true) ?: detail?.title() ?: ""
|
||||||
Log.i("YT View Model",detail.toString())
|
Log.i("YT View Model",detail.toString())
|
||||||
ytTrackList.postValue(listOf(TrackDetails(
|
ytTrackList.postValue(
|
||||||
|
listOf(TrackDetails(
|
||||||
title = name,
|
title = name,
|
||||||
artists = listOf(detail?.author().toString()),
|
artists = listOf(detail?.author().toString()),
|
||||||
durationSec = detail?.lengthSeconds()?:0,
|
durationSec = detail?.lengthSeconds()?:0,
|
||||||
@ -115,7 +133,8 @@ class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
Provider.defaultDir +".Images/" + searchId + ".jpeg"
|
Provider.defaultDir +".Images/" + searchId + ".jpeg"
|
||||||
),
|
),
|
||||||
source = Source.YouTube
|
source = Source.YouTube
|
||||||
)))
|
)).toMutableList()
|
||||||
|
)
|
||||||
title.postValue(
|
title.postValue(
|
||||||
if(name.length > 17){"${name.subSequence(0,16)}..."}else{name}
|
if(name.length > 17){"${name.subSequence(0,16)}..."}else{name}
|
||||||
)
|
)
|
||||||
@ -125,13 +144,16 @@ class YoutubeViewModel @ViewModelInject constructor(val databaseDAO: DatabaseDAO
|
|||||||
type = "Track",
|
type = "Track",
|
||||||
name = if(name.length > 17){"${name.subSequence(0,16)}..."}else{name},
|
name = if(name.length > 17){"${name.subSequence(0,16)}..."}else{name},
|
||||||
link = "https://www.youtube.com/watch?v=$searchId",
|
link = "https://www.youtube.com/watch?v=$searchId",
|
||||||
coverUrl = "https://i.ytimg.com/vi/$searchId/maxresdefault.jpg",
|
coverUrl = "https://i.ytimg.com/vi/$searchId/hqdefault.jpg",
|
||||||
totalFiles = 1,
|
totalFiles = 1,
|
||||||
downloaded = false,
|
downloaded = false,
|
||||||
directory = finalOutputDir(type = "YT_Downloads")
|
directory = finalOutputDir(type = "YT_Downloads")
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e:com.github.kiulian.downloader.YoutubeException){
|
||||||
|
showToast("An Error Occurred While Processing!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ package com.shabinder.spotiflyer.utils
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
|
import android.widget.Toast
|
||||||
import com.github.kiulian.downloader.YoutubeDownloader
|
import com.github.kiulian.downloader.YoutubeDownloader
|
||||||
import com.shabinder.spotiflyer.App
|
import com.shabinder.spotiflyer.App
|
||||||
import com.shabinder.spotiflyer.MainActivity
|
import com.shabinder.spotiflyer.MainActivity
|
||||||
@ -117,4 +118,7 @@ object Provider {
|
|||||||
return retrofit.create(YoutubeMusicApi::class.java)
|
return retrofit.create(YoutubeMusicApi::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showToast(string: String,long:Boolean=false){
|
||||||
|
Toast.makeText(activity,string,if(long)Toast.LENGTH_LONG else Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
}
|
}
|
@ -28,7 +28,6 @@ import android.view.animation.RotateAnimation
|
|||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import androidx.databinding.BindingAdapter
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.DataSource
|
import com.bumptech.glide.load.DataSource
|
||||||
import com.bumptech.glide.load.engine.GlideException
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
@ -77,8 +76,7 @@ fun rotateAnim(view: View){
|
|||||||
view.animation = rotate
|
view.animation = rotate
|
||||||
}
|
}
|
||||||
|
|
||||||
@BindingAdapter("imageUrl")
|
fun bindImage(imgView: ImageView, imgUrl: String?,source: Source?) {
|
||||||
fun bindImage(imgView: ImageView, imgUrl: String?,source: Source) {
|
|
||||||
imgUrl?.let {
|
imgUrl?.let {
|
||||||
val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()
|
val imgUri = imgUrl.toUri().buildUpon().scheme("https").build()
|
||||||
Glide
|
Glide
|
||||||
@ -122,6 +120,10 @@ fun bindImage(imgView: ImageView, imgUrl: String?,source: Source) {
|
|||||||
defaultDir+".Images/" + imgUrl.substringBeforeLast('/',imgUrl).substringAfterLast('/',imgUrl) + ".jpeg"
|
defaultDir+".Images/" + imgUrl.substringBeforeLast('/',imgUrl).substringAfterLast('/',imgUrl) + ".jpeg"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
else -> File(
|
||||||
|
Environment.getExternalStorageDirectory(),
|
||||||
|
defaultDir+".Images/" + imgUrl.substringAfterLast('/',imgUrl) + ".jpeg"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
// the File to save , append increasing numeric counter to prevent files from getting overwritten.
|
// the File to save , append increasing numeric counter to prevent files from getting overwritten.
|
||||||
resource?.copyTo(file)
|
resource?.copyTo(file)
|
||||||
|
Loading…
Reference in New Issue
Block a user