mirror of
https://github.com/zoriya/Opus.git
synced 2025-12-06 06:26:15 +00:00
Updating the parsing method, make it work with every queue change possible.
This commit is contained in:
@@ -21,6 +21,7 @@ using Com.Google.Android.Exoplayer2.Trackselection;
|
||||
using Com.Google.Android.Exoplayer2.Upstream;
|
||||
using Com.Google.Android.Exoplayer2.Util;
|
||||
using Newtonsoft.Json;
|
||||
using Opus.Code.Api;
|
||||
using Opus.DataStructure;
|
||||
using Opus.Fragments;
|
||||
using Opus.Others;
|
||||
@@ -63,7 +64,6 @@ namespace Opus.Api.Services
|
||||
public static bool isRunning = false;
|
||||
private bool generating = false;
|
||||
public static int currentID = 0;
|
||||
public static int switchPosition;
|
||||
public static bool autoUpdateSeekBar = true;
|
||||
public static bool repeat = false;
|
||||
public static bool useAutoPlay = true;
|
||||
@@ -367,10 +367,10 @@ namespace Opus.Api.Services
|
||||
public async void Play(Song song, long progress = -1, bool addToQueue = true)
|
||||
{
|
||||
if (song.IsParsed == false)
|
||||
await ParseSong(song, -1);
|
||||
await new SongParser().ParseSong(song, -1);
|
||||
else if (song.IsParsed == null)
|
||||
{
|
||||
await ParseSong(song, -1, true);
|
||||
await new SongParser().ParseSong(song, -1, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -423,147 +423,6 @@ namespace Opus.Api.Services
|
||||
GenerateAutoPlay(false);
|
||||
}
|
||||
|
||||
private static async Task<Song> ParseSong(Song song, int position = -1, bool startPlaybackWhenPosible = false, bool forceParse = false)
|
||||
{
|
||||
if ((!forceParse && song.IsParsed == true) || !song.IsYt)
|
||||
{
|
||||
if (startPlaybackWhenPosible)
|
||||
instance.Play(song, -1, position == -1);
|
||||
|
||||
return song;
|
||||
}
|
||||
|
||||
if (song.IsParsed == null)
|
||||
{
|
||||
while (song.IsParsed == null)
|
||||
await Task.Delay(10);
|
||||
|
||||
if (startPlaybackWhenPosible && (await GetItem()).YoutubeID != song.YoutubeID)
|
||||
instance.Play(song, -1, position == -1);
|
||||
|
||||
return song; //Song is a class, the youtube id will be updated with another method
|
||||
}
|
||||
|
||||
switchPosition = position;
|
||||
|
||||
try
|
||||
{
|
||||
song.IsParsed = null;
|
||||
YoutubeClient client = new YoutubeClient();
|
||||
var mediaStreamInfo = await client.GetVideoMediaStreamInfosAsync(song.YoutubeID);
|
||||
if (mediaStreamInfo.HlsLiveStreamUrl != null)
|
||||
{
|
||||
song.Path = mediaStreamInfo.HlsLiveStreamUrl;
|
||||
song.IsLiveStream = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
song.IsLiveStream = false;
|
||||
|
||||
if (mediaStreamInfo.Audio.Count > 0)
|
||||
song.Path = mediaStreamInfo.Audio.OrderBy(s => s.Bitrate).Last().Url;
|
||||
else if (mediaStreamInfo.Muxed.Count > 0)
|
||||
song.Path = mediaStreamInfo.Muxed.OrderBy(x => x.Resolution).Last().Url;
|
||||
else
|
||||
{
|
||||
MainActivity.instance.NotStreamable(song.Title);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
song.IsParsed = true;
|
||||
|
||||
if (switchPosition != -1)
|
||||
Queue.instance?.NotifyItemChanged(switchPosition, Resource.Drawable.PublicIcon);
|
||||
|
||||
if (startPlaybackWhenPosible && song.Album != null)
|
||||
{
|
||||
if(switchPosition != -1)
|
||||
{
|
||||
currentID = switchPosition;
|
||||
Queue.instance?.RefreshCurrent();
|
||||
Player.instance?.RefreshPlayer();
|
||||
}
|
||||
|
||||
instance.Play(song, -1, switchPosition == -1);
|
||||
startPlaybackWhenPosible = false;
|
||||
}
|
||||
|
||||
Video video = await client.GetVideoAsync(song.YoutubeID);
|
||||
song.Title = video.Title;
|
||||
song.Artist = video.Author;
|
||||
song.Album = await YoutubeManager.GetBestThumb(new string[] { video.Thumbnails.MaxResUrl, video.Thumbnails.StandardResUrl, video.Thumbnails.HighResUrl });
|
||||
song.Duration = (int)video.Duration.TotalMilliseconds;
|
||||
Player.instance?.RefreshPlayer();
|
||||
|
||||
if (startPlaybackWhenPosible)
|
||||
{
|
||||
instance.Play(song, -1, switchPosition == -1);
|
||||
|
||||
if (switchPosition != -1)
|
||||
{
|
||||
Queue.instance?.NotifyItemChanged(switchPosition, song.Artist);
|
||||
Home.instance?.NotifyQueueChanged(switchPosition, song.Artist);
|
||||
}
|
||||
}
|
||||
|
||||
if (!song.IsLiveStream)
|
||||
song.ExpireDate = mediaStreamInfo.ValidUntil;
|
||||
|
||||
if(switchPosition != -1)
|
||||
UpdateQueueItemDB(song, switchPosition);
|
||||
|
||||
switchPosition = -1;
|
||||
}
|
||||
catch (System.Net.Http.HttpRequestException)
|
||||
{
|
||||
Console.WriteLine("&Parse time out");
|
||||
MainActivity.instance.Timout();
|
||||
if (MainActivity.instance != null)
|
||||
MainActivity.instance.FindViewById<ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
|
||||
song.IsParsed = false;
|
||||
|
||||
if (startPlaybackWhenPosible)
|
||||
Player.instance?.Ready();
|
||||
|
||||
switchPosition = -1;
|
||||
return null;
|
||||
}
|
||||
catch(YoutubeExplode.Exceptions.VideoUnplayableException ex)
|
||||
{
|
||||
Console.WriteLine("&Parse error: " + ex.Message);
|
||||
MainActivity.instance.Unplayable(song.Title, ex.Message);
|
||||
if (MainActivity.instance != null)
|
||||
MainActivity.instance.FindViewById<ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
|
||||
|
||||
song.IsParsed = false;
|
||||
if (switchPosition != -1)
|
||||
RemoveFromQueue(switchPosition); //Remove the song from the queue since it can't be played.
|
||||
|
||||
if(startPlaybackWhenPosible)
|
||||
Player.instance?.Ready();
|
||||
|
||||
switchPosition = -1;
|
||||
return null;
|
||||
}
|
||||
catch(YoutubeExplode.Exceptions.VideoUnavailableException)
|
||||
{
|
||||
MainActivity.instance.NotStreamable(song.Title);
|
||||
if (MainActivity.instance != null)
|
||||
MainActivity.instance.FindViewById<ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
|
||||
|
||||
song.IsParsed = false;
|
||||
if (switchPosition != -1)
|
||||
RemoveFromQueue(switchPosition); //Remove the song from the queue since it can't be played.
|
||||
|
||||
if (startPlaybackWhenPosible)
|
||||
Player.instance?.Ready();
|
||||
|
||||
switchPosition = -1;
|
||||
return null;
|
||||
}
|
||||
return song;
|
||||
}
|
||||
|
||||
private async void ParseAndPlay(string action, string videoID, string title, string artist, string thumbnailURL, bool showPlayer = true)
|
||||
{
|
||||
if (MainActivity.instance != null && action == "Play")
|
||||
@@ -589,11 +448,11 @@ namespace Opus.Api.Services
|
||||
Queue.instance?.Refresh();
|
||||
Player.instance?.RefreshPlayer();
|
||||
currentID = 0;
|
||||
await ParseSong(song, 0, true);
|
||||
await new SongParser().ParseSong(song, 0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Song song = await ParseSong(new Song(title, artist, thumbnailURL, videoID, -1, -1, null, true, false));
|
||||
Song song = await new SongParser().ParseSong(new Song(title, artist, thumbnailURL, videoID, -1, -1, null, true, false));
|
||||
if (song == null) //The song can't be played, do not add it to the queue
|
||||
return;
|
||||
|
||||
@@ -763,6 +622,7 @@ namespace Opus.Api.Services
|
||||
|
||||
private void RandomizeQueue()
|
||||
{
|
||||
SongParser.CancelAll();
|
||||
Random r = new Random();
|
||||
if (UseCastPlayer)
|
||||
{
|
||||
@@ -799,6 +659,7 @@ namespace Opus.Api.Services
|
||||
song = new Song(title, artist, thumbnailURI, youtubeID, -1, -1, filePath, true);
|
||||
|
||||
song.IsLiveStream = isLive;
|
||||
SongParser.QueueSlotAdded(CurrentID() + 1);
|
||||
queue.Insert(CurrentID() + 1, song);
|
||||
Home.instance?.NotifyQueueInserted(CurrentID() + 1);
|
||||
Queue.instance?.NotifyItemInserted(CurrentID() + 1);
|
||||
@@ -821,6 +682,7 @@ namespace Opus.Api.Services
|
||||
|
||||
public void AddToQueue(Song song)
|
||||
{
|
||||
SongParser.QueueSlotAdded(CurrentID() + 1);
|
||||
queue.Insert(CurrentID() + 1, song);
|
||||
Home.instance?.NotifyQueueInserted(CurrentID() + 1);
|
||||
Queue.instance?.NotifyItemInserted(CurrentID() + 1);
|
||||
@@ -843,6 +705,7 @@ namespace Opus.Api.Services
|
||||
|
||||
public async void AddToQueue(IEnumerable<Song> songs)
|
||||
{
|
||||
SongParser.CancelAll();
|
||||
queue.AddRange(songs);
|
||||
Home.instance?.RefreshQueue();
|
||||
Queue.instance?.Refresh();
|
||||
@@ -851,12 +714,13 @@ namespace Opus.Api.Services
|
||||
if (UseCastPlayer)
|
||||
{
|
||||
foreach (Song song in songs)
|
||||
RemotePlayer.QueueAppendItem(GetQueueItem(await ParseSong(song)), null);
|
||||
RemotePlayer.QueueAppendItem(GetQueueItem(await new SongParser().ParseSong(song)), null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void InsertToQueue(int position, Song song)
|
||||
{
|
||||
SongParser.QueueSlotAdded(position);
|
||||
queue.Insert(position, song);
|
||||
Home.instance?.NotifyQueueInserted(position);
|
||||
Queue.instance?.NotifyItemInserted(position);
|
||||
@@ -869,6 +733,7 @@ namespace Opus.Api.Services
|
||||
|
||||
public void InsertToQueue(int position, Song[] songs)
|
||||
{
|
||||
SongParser.QueueSlotAdded(position);
|
||||
queue.InsertRange(position, songs);
|
||||
Home.instance?.NotifyQueueRangeInserted(position, songs.Length);
|
||||
Queue.instance?.NotifyItemRangeInserted(position, songs.Length);
|
||||
@@ -897,9 +762,7 @@ namespace Opus.Api.Services
|
||||
Queue.instance?.RefreshCurrent();
|
||||
}
|
||||
|
||||
//Switch position is the position of the song that will be played just after the parsing.
|
||||
if (switchPosition > position)
|
||||
switchPosition--;
|
||||
SongParser.QueueSlotRemoved(position);
|
||||
|
||||
SaveQueueSlot();
|
||||
queue.RemoveAt(position);
|
||||
@@ -1083,7 +946,7 @@ namespace Opus.Api.Services
|
||||
parseProgress.Visibility = ViewStates.Visible;
|
||||
parseProgress.ScaleY = 6;
|
||||
}
|
||||
await ParseSong(song, position, !UseCastPlayer, true);
|
||||
await new SongParser().ParseSong(song, position, !UseCastPlayer, true);
|
||||
|
||||
if (song == null) //Check if the parse has succeed, the song is set to null if there is an error
|
||||
Player.instance?.Ready(); //Remove player's loading bar since we'll not load this song
|
||||
@@ -1262,7 +1125,7 @@ namespace Opus.Api.Services
|
||||
Song song = autoPlay[0];
|
||||
if (song.IsParsed != false || !song.IsYt)
|
||||
return;
|
||||
await ParseSong(song);
|
||||
await new SongParser().ParseSong(song);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1271,7 +1134,7 @@ namespace Opus.Api.Services
|
||||
if (song.IsParsed != false || !song.IsYt)
|
||||
return;
|
||||
|
||||
await ParseSong(song, currentID + 1);
|
||||
await new SongParser().ParseSong(song, currentID + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1290,7 +1153,7 @@ namespace Opus.Api.Services
|
||||
{
|
||||
Song song = await GetItem();
|
||||
if (song.IsYt && song.IsParsed != true)
|
||||
await ParseSong(song);
|
||||
await new SongParser().ParseSong(song);
|
||||
else if(!song.IsYt)
|
||||
{
|
||||
MediaMetadataRetriever meta = new MediaMetadataRetriever();
|
||||
@@ -1578,7 +1441,7 @@ namespace Opus.Api.Services
|
||||
for (int i = 0; i < queue.Count; i++)
|
||||
{
|
||||
if (queue[i].IsYt && queue[i].IsParsed != true)
|
||||
queue[i] = await ParseSong(queue[i], i);
|
||||
queue[i] = await new SongParser().ParseSong(queue[i], i);
|
||||
}
|
||||
|
||||
if(showToast)
|
||||
|
||||
227
Opus/Code/Api/SongParser.cs
Normal file
227
Opus/Code/Api/SongParser.cs
Normal file
@@ -0,0 +1,227 @@
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Opus.Api;
|
||||
using Opus.Api.Services;
|
||||
using Opus.DataStructure;
|
||||
using Opus.Fragments;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using YoutubeExplode;
|
||||
using YoutubeExplode.Models;
|
||||
|
||||
namespace Opus.Code.Api
|
||||
{
|
||||
public class SongParser
|
||||
{
|
||||
private static readonly List<SongParser> instances = new List<SongParser>();
|
||||
private int queuePosition = -1;
|
||||
private bool canceled = false;
|
||||
|
||||
public SongParser()
|
||||
{
|
||||
instances.Add(this);
|
||||
}
|
||||
|
||||
|
||||
#region queuePosition updates
|
||||
public static void QueueSlotAdded(int newPos)
|
||||
{
|
||||
foreach(SongParser instance in instances)
|
||||
{
|
||||
if (newPos < instance.queuePosition)
|
||||
instance.queuePosition++;
|
||||
}
|
||||
}
|
||||
|
||||
public static void QueueSlotMoved(int oldPos, int newPos)
|
||||
{
|
||||
foreach (SongParser instance in instances)
|
||||
{
|
||||
if (oldPos == instance.queuePosition)
|
||||
instance.queuePosition = newPos;
|
||||
else if (oldPos < instance.queuePosition)
|
||||
instance.queuePosition--;
|
||||
else if (oldPos > instance.queuePosition && newPos < instance.queuePosition)
|
||||
instance.queuePosition++;
|
||||
}
|
||||
}
|
||||
|
||||
public static void QueueSlotRemoved(int removedPosition)
|
||||
{
|
||||
foreach (SongParser instance in instances)
|
||||
{
|
||||
if (removedPosition < instance.queuePosition)
|
||||
instance.queuePosition--;
|
||||
else if (removedPosition == instance.queuePosition)
|
||||
instance.Cancel();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Method that complete the song you give to make it playable with the player. Used only for youtube songs but you can give local songs here, that won't hurt.
|
||||
/// </summary>
|
||||
/// <param name="song">The song you want to complete</param>
|
||||
/// <param name="position">If the song is in the queue, set this parameter to the song's queue position. It will give display callbacks.</param>
|
||||
/// <param name="startPlaybackWhenPosible">Set this to true if you want to start playing the song before the end of this method.</param>
|
||||
/// <param name="forceParse">Set this to true if you want this method to retrieve steams info from youtube even if the song said that it is already parsed.</param>
|
||||
/// <returns></returns>
|
||||
public async Task<Song> ParseSong(Song song, int position = -1, bool startPlaybackWhenPosible = false, bool forceParse = false)
|
||||
{
|
||||
queuePosition = position;
|
||||
|
||||
if ((!forceParse && song.IsParsed == true) || !song.IsYt)
|
||||
{
|
||||
if (startPlaybackWhenPosible)
|
||||
MusicPlayer.instance.Play(song, -1, queuePosition == -1);
|
||||
|
||||
return song;
|
||||
}
|
||||
|
||||
if (song.IsParsed == null)
|
||||
{
|
||||
while (song.IsParsed == null)
|
||||
await Task.Delay(10);
|
||||
|
||||
if (canceled)
|
||||
return song;
|
||||
|
||||
if (startPlaybackWhenPosible && (await MusicPlayer.GetItem()).YoutubeID != song.YoutubeID)
|
||||
MusicPlayer.instance.Play(song, -1, queuePosition == -1);
|
||||
|
||||
return song; //Song is a class, the youtube id will be updated with another method
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
song.IsParsed = null;
|
||||
YoutubeClient client = new YoutubeClient();
|
||||
var mediaStreamInfo = await client.GetVideoMediaStreamInfosAsync(song.YoutubeID);
|
||||
if (mediaStreamInfo.HlsLiveStreamUrl != null)
|
||||
{
|
||||
song.Path = mediaStreamInfo.HlsLiveStreamUrl;
|
||||
song.IsLiveStream = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
song.IsLiveStream = false;
|
||||
|
||||
if (mediaStreamInfo.Audio.Count > 0)
|
||||
song.Path = mediaStreamInfo.Audio.OrderBy(s => s.Bitrate).Last().Url;
|
||||
else if (mediaStreamInfo.Muxed.Count > 0)
|
||||
song.Path = mediaStreamInfo.Muxed.OrderBy(x => x.Resolution).Last().Url;
|
||||
else
|
||||
{
|
||||
MainActivity.instance.NotStreamable(song.Title);
|
||||
return null;
|
||||
}
|
||||
|
||||
song.ExpireDate = mediaStreamInfo.ValidUntil;
|
||||
}
|
||||
song.IsParsed = true;
|
||||
|
||||
if (queuePosition != -1)
|
||||
Queue.instance?.NotifyItemChanged(queuePosition, Resource.Drawable.PublicIcon);
|
||||
|
||||
if (canceled)
|
||||
return song;
|
||||
|
||||
if (startPlaybackWhenPosible && song.Album != null)
|
||||
{
|
||||
if (queuePosition != -1)
|
||||
{
|
||||
MusicPlayer.currentID = queuePosition;
|
||||
Queue.instance?.RefreshCurrent();
|
||||
Player.instance?.RefreshPlayer();
|
||||
}
|
||||
|
||||
MusicPlayer.instance.Play(song, -1, queuePosition == -1);
|
||||
startPlaybackWhenPosible = false;
|
||||
}
|
||||
|
||||
Video video = await client.GetVideoAsync(song.YoutubeID);
|
||||
song.Title = video.Title;
|
||||
song.Artist = video.Author;
|
||||
song.Album = await YoutubeManager.GetBestThumb(new string[] { video.Thumbnails.MaxResUrl, video.Thumbnails.StandardResUrl, video.Thumbnails.HighResUrl });
|
||||
song.Duration = (int)video.Duration.TotalMilliseconds;
|
||||
|
||||
if (queuePosition == MusicPlayer.CurrentID())
|
||||
Player.instance?.RefreshPlayer();
|
||||
|
||||
if (queuePosition != -1)
|
||||
{
|
||||
Queue.instance?.NotifyItemChanged(queuePosition, song.Artist);
|
||||
Home.instance?.NotifyQueueChanged(queuePosition, song.Artist);
|
||||
}
|
||||
|
||||
if (canceled)
|
||||
return song;
|
||||
|
||||
if (startPlaybackWhenPosible)
|
||||
MusicPlayer.instance.Play(song, -1, queuePosition == -1);
|
||||
}
|
||||
catch (System.Net.Http.HttpRequestException)
|
||||
{
|
||||
Console.WriteLine("&Parse time out");
|
||||
MainActivity.instance.Timout();
|
||||
if (MainActivity.instance != null)
|
||||
MainActivity.instance.FindViewById<ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
|
||||
song.IsParsed = false;
|
||||
|
||||
if (startPlaybackWhenPosible)
|
||||
Player.instance?.Ready();
|
||||
}
|
||||
catch (YoutubeExplode.Exceptions.VideoUnplayableException ex)
|
||||
{
|
||||
Console.WriteLine("&Parse error: " + ex.Message);
|
||||
MainActivity.instance.Unplayable(song.Title, ex.Message);
|
||||
if (MainActivity.instance != null)
|
||||
MainActivity.instance.FindViewById<ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
|
||||
|
||||
song.IsParsed = false;
|
||||
if (queuePosition != -1)
|
||||
MusicPlayer.RemoveFromQueue(queuePosition); //Remove the song from the queue since it can't be played.
|
||||
|
||||
if (startPlaybackWhenPosible)
|
||||
Player.instance?.Ready();
|
||||
}
|
||||
catch (YoutubeExplode.Exceptions.VideoUnavailableException)
|
||||
{
|
||||
MainActivity.instance.NotStreamable(song.Title);
|
||||
if (MainActivity.instance != null)
|
||||
MainActivity.instance.FindViewById<ProgressBar>(Resource.Id.ytProgress).Visibility = ViewStates.Gone;
|
||||
|
||||
song.IsParsed = false;
|
||||
if (queuePosition != -1)
|
||||
MusicPlayer.RemoveFromQueue(queuePosition); //Remove the song from the queue since it can't be played.
|
||||
|
||||
if (startPlaybackWhenPosible)
|
||||
Player.instance?.Ready();
|
||||
}
|
||||
|
||||
queuePosition = -1;
|
||||
instances.Remove(this);
|
||||
return song;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This method will remove playback calls and get requests from the
|
||||
/// </summary>
|
||||
private void Cancel()
|
||||
{
|
||||
instances.Remove(this);
|
||||
canceled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This will cancel all parse (by calling the cancel method on all instances). Use this when the queue has too many changes to track them.
|
||||
/// </summary>
|
||||
public static void CancelAll()
|
||||
{
|
||||
while(instances.Count > 0)
|
||||
instances[0].Cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ namespace Opus.Others
|
||||
if (alwaysAllowSwap && (viewHolder.AdapterPosition + 1 == ((QueueAdapter)adapter).ItemCount || viewHolder.AdapterPosition == 0))
|
||||
return MakeFlag(0, 0);
|
||||
|
||||
if (alwaysAllowSwap && (MusicPlayer.CurrentID() + 1 == viewHolder.AdapterPosition || MusicPlayer.switchPosition + 1 == viewHolder.AdapterPosition))
|
||||
if (alwaysAllowSwap && /*(*/MusicPlayer.CurrentID() + 1 == viewHolder.AdapterPosition/* || MusicPlayer.switchPosition + 1 == viewHolder.AdapterPosition)*/)
|
||||
return MakeMovementFlags(dragFlag, 0);
|
||||
|
||||
return MakeMovementFlags(dragFlag, swipeFlag);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Content.Res;
|
||||
using Android.Graphics;
|
||||
using Android.Support.Design.Widget;
|
||||
using Android.Support.V7.Widget;
|
||||
@@ -9,6 +8,7 @@ using Android.Text.Style;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Opus.Api.Services;
|
||||
using Opus.Code.Api;
|
||||
using Opus.DataStructure;
|
||||
using Opus.Others;
|
||||
using Square.Picasso;
|
||||
@@ -326,6 +326,7 @@ namespace Opus.Adapter
|
||||
|
||||
if (int.TryParse(payloads[0].ToString(), out int payload) && payload == Resource.Drawable.PublicIcon)
|
||||
{
|
||||
if(MusicPlayer.queue[position - 1].IsParsed == true)
|
||||
holder.youtubeIcon.SetImageResource(Resource.Drawable.PublicIcon);
|
||||
return;
|
||||
}
|
||||
@@ -425,6 +426,8 @@ namespace Opus.Adapter
|
||||
else if (MusicPlayer.CurrentID() == fromPosition)
|
||||
MusicPlayer.currentID = toPosition;
|
||||
|
||||
SongParser.QueueSlotMoved(fromPosition, toPosition);
|
||||
|
||||
if (MusicPlayer.UseCastPlayer)
|
||||
{
|
||||
int nextItemID = MusicPlayer.RemotePlayer.MediaQueue.ItemCount > toPosition ? MusicPlayer.RemotePlayer.MediaQueue.ItemIdAtIndex(toPosition + 1) : 0; //0 = InvalidItemID = end of the queue
|
||||
|
||||
@@ -324,6 +324,7 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Code\Api\SongParser.cs" />
|
||||
<Compile Include="Code\DataStructure\SearchableList.cs" />
|
||||
<Compile Include="Code\UI\Adapter\BaseCursor.cs" />
|
||||
<Compile Include="Code\Api\LocalManager.cs" />
|
||||
|
||||
Reference in New Issue
Block a user