[Banshee-List] Play Queue: Auto DJ and Party Mode




I have been playing around with Banshee on Ubuntu after just coming over from Windows. I used MediaMonkey on WinXP and liked a couple of the features:
  • Auto-DJ: when the play queue is complete random tracks are automatically added from the library.
  • Party Mode: A locked down mode you can use in a party where people can add tracks to the play queue but can't delete them or reorder them (everyone likes their songs first).
  • Play Queue Mode: tracks doubled clicked on in the library are added to the play queue and all songs are played through the play queue.
I couldn't find anything like this so I have made an attempt at it myself. Most of the code I have changed is in the Play Queue extension but also I made the ReorderSelectedTracks method in PlayListSource virtual so I can stop tracks being re-ordered.

Being a newbie I have a few questions:
  1. How can I select tracks from a playlist (smart or normal) for auto-dj?
  2. What is the best way to create a dialog  in GTK  that allows options to be set: party mode password, play list or entire library for auto-dj, number of tracks to add, etc.
  3. Is their an alternative way to stop the tracks be re-ordered? I tried  DatabaseTrackModel.CanReorder = true but it seems to only work during initialisation.
  4. How can I stop the double click on the play  queue from playing that track? I want only the first track to be playing.
I have attached the project so you can try it out with a diff file. Use the Play queue context menu to get it going. I am having one problem where existing tracks in the queue are added to the end. It seems quite random but I think it happens during the transition from one track to another. Any help appreciated.

Thanks Tim
Index: src/Extensions/Banshee.PlayQueue/Resources/ActiveSourceUI.xml
===================================================================
--- src/Extensions/Banshee.PlayQueue/Resources/ActiveSourceUI.xml	(revision 4875)
+++ src/Extensions/Banshee.PlayQueue/Resources/ActiveSourceUI.xml	(working copy)
@@ -1,6 +1,7 @@
 <ui>
     <toolbar name="HeaderToolbar">
         <placeholder name="SourceActions">
+        	<toolitem action="RandomTracksAction" />
             <toolitem action="ClearPlayQueueAction" />
         </placeholder>
     </toolbar>
Index: src/Extensions/Banshee.PlayQueue/Resources/GlobalUI.xml
===================================================================
--- src/Extensions/Banshee.PlayQueue/Resources/GlobalUI.xml	(revision 4875)
+++ src/Extensions/Banshee.PlayQueue/Resources/GlobalUI.xml	(working copy)
@@ -2,10 +2,17 @@
     <popup name="PlayQueueContextMenu">
         <menuitem action="ClearPlayQueueAction"></menuitem>
         <menuitem action="ClearPlayQueueOnQuitAction"></menuitem>
+		<menuitem action="RandomTracksAction"></menuitem>
+		<menuitem action="PartyModeAction"></menuitem>
+		<menu name="PlayQueueOptions" action="PlayQueueOptionsAction">
+    		<menuitem action="AutoDJAction"></menuitem>
+    		<menuitem action="PlayQueueModeAction"></menuitem>	
+		</menu>	
     </popup>
     <popup name="TrackContextMenu" action="TrackContextMenuAction">
         <placeholder name="AboveAddToPlaylist">
             <menuitem name="AddToPlayQueue" action="AddToPlayQueueAction"></menuitem>
+            <menuitem name="AddAllToPlayQueue" action="AddAllToPlayQueueAction"></menuitem>
         </placeholder>
     </popup>
-</ui>
\ No newline at end of file
+</ui>
Index: src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueActions.cs
===================================================================
--- src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueActions.cs	(revision 4875)
+++ src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueActions.cs	(working copy)
@@ -50,6 +50,13 @@
                     Catalog.GetString ("Append selected songs to the play queue"),
                     OnAddToPlayQueue)
             });
+                
+            Add (new ActionEntry [] {
+                new ActionEntry ("AddAllToPlayQueueAction", Stock.Add,
+                    Catalog.GetString ("Add all to Play Queue"), "q",
+                    Catalog.GetString ("Append all songs to play queue"),
+                    OnAddAllToPlayQueue)
+            });
             
             AddImportant (
                 new ActionEntry ("ClearPlayQueueAction", Stock.Clear,
@@ -64,6 +71,38 @@
                     Catalog.GetString ("Clear the play queue when quitting"), 
                     OnClearPlayQueueOnQuit, PlayQueueSource.ClearOnQuitSchema.Get ())
             });
+                        
+            Add (new ToggleActionEntry [] {
+                new ToggleActionEntry ("PartyModeAction", null,
+                    Catalog.GetString ("Party Mode"), null,
+                    Catalog.GetString ("Tracks can be added not reordered or removed."),
+                    OnPartyMode, false)
+            });
+                                
+            Add (new ActionEntry [] {
+                new ActionEntry ("RandomTracksAction", Stock.Add,
+                    Catalog.GetString ("Random Tracks"), null,
+                    Catalog.GetString ("Append random songs to the play queue"),
+                    OnRandomTracks)
+            });
+                                
+            Add (new ActionEntry [] {
+                new ActionEntry ("PlayQueueOptionsAction", null, Catalog.GetString ("Options"), null, null, null)
+            });
+                                                                                             
+            Add (new ToggleActionEntry [] {
+                new ToggleActionEntry ("AutoDJAction", null,
+                    Catalog.GetString ("Auto DJ"), null,
+                    Catalog.GetString ("Add extra tracks when queue is empty"),
+                    OnAutoDJ, PlayQueueSource.AutoDJSchema.Get ())
+            });
+                            
+            Add (new ToggleActionEntry [] {
+                new ToggleActionEntry ("PlayQueueModeAction", null,
+                    Catalog.GetString ("Play Queue Mode"), null,
+                    Catalog.GetString ("All tracks are played through the queue"),
+                    OnPlayQueueMode, PlayQueueSource.PlayQueueModeSchema.Get ())
+            });
             
             AddUiFromFile ("GlobalUI.xml");
 
@@ -88,7 +127,12 @@
         {
             playqueue.AddSelectedTracks (ServiceManager.SourceManager.ActiveSource);
         }
-
+                                
+        private void OnAddAllToPlayQueue (object o, EventArgs args)
+        {
+            playqueue.AddAllTracks (ServiceManager.SourceManager.ActiveSource);
+        }
+                        
         private void OnClearPlayQueue (object o, EventArgs args)
         {
             playqueue.Clear ();
@@ -100,6 +144,30 @@
             PlayQueueSource.ClearOnQuitSchema.Set (action.Active);
         }
 
+        private void OnRandomTracks (object o, EventArgs args)
+        {
+            playqueue.AddRandomTracks(5);
+        }                        
+                        
+        private void OnAutoDJ (object o, EventArgs args)
+        {
+            ToggleAction action = this["AutoDJAction"] as Gtk.ToggleAction;
+            PlayQueueSource.AutoDJSchema.Set (action.Active);
+        }
+                                    
+        private void OnPlayQueueMode (object o, EventArgs args)
+        {
+            ToggleAction action = this["PlayQueueModeAction"] as Gtk.ToggleAction;
+            PlayQueueSource.PlayQueueModeSchema.Set (action.Active);
+        }
+                        
+        private void OnPartyMode (object o, EventArgs args)
+        {
+            ToggleAction action = this["PartyModeAction"] as Gtk.ToggleAction;                                 
+            playqueue.IsPartyMode = action.Active; 
+            UpdateActions ();
+        }
+
         #endregion
 
         private void OnSourceUpdated (SourceEventArgs args)
@@ -117,8 +185,13 @@
             Source source = ServiceManager.SourceManager.ActiveSource;
             if (source != null) {
                 DatabaseSource db_source = source as DatabaseSource ?? source.Parent as DatabaseSource;
-                UpdateAction ("ClearPlayQueueAction", true, playqueue.Count > 0);
+                UpdateAction ("ClearPlayQueueAction", !playqueue.IsPartyMode, playqueue.Count > 0);
+                UpdateAction ("AutoDJAction", !playqueue.IsPartyMode);
+                UpdateAction ("PlayQueueModeAction", !playqueue.IsPartyMode);
+                UpdateAction ("RandomTracksAction", !playqueue.IsPartyMode);
+                UpdateAction ("ClearPlayQueueOnQuitAction", !playqueue.IsPartyMode);
                 UpdateAction ("AddToPlayQueueAction", db_source != null && db_source != playqueue, true);
+                UpdateAction ("AddAllToPlayQueueAction", db_source != null && db_source != playqueue, true);
             }
         }
     }
Index: src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs
===================================================================
--- src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs	(revision 4875)
+++ src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs	(working copy)
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Collections.Generic;
 
 using Mono.Unix;
 
@@ -55,6 +56,9 @@
         private TrackInfo prior_playback_track;
         private PlayQueueActions actions;
         private bool was_playing = false;
+        private bool is_party_mode = false;
+        private InterfaceActionService uia_service;
+        private bool track_intercept = false;
         
         protected override bool HasArtistAlbum {
             get { return false; }
@@ -62,6 +66,7 @@
         
         public PlayQueueSource () : base (Catalog.GetString ("Play Queue"), null)
         {
+            
             BindToDatabase ();
             TypeUniqueId = DbId.ToString ();
             Initialize ();
@@ -102,6 +107,13 @@
             
             Reload ();
             SetAsPlaybackSourceUnlessPlaying ();
+            
+            uia_service = ServiceManager.Get<InterfaceActionService> ();
+            uia_service.TrackActions.PreActivate += TrackActionPreActivate;
+            
+            // Intercept tracks starting to play
+            ServiceManager.PlayerEngine.TrackIntercept += TrackIntercept;
+                
         }
         
 #region IPlayQueue, IDBusExportable
@@ -155,6 +167,43 @@
 
 #endregion
         
+        private bool TrackIntercept (TrackInfo track)
+        {
+            
+            // Only intercept when in Play Queue Mode
+            if(PlayQueueSource.PlayQueueModeSchema.Get () == false)
+                return false;
+            
+            // Do nothing if the play queue is the active source and not in party mode
+            if (ServiceManager.SourceManager.ActiveSource == this)   
+                return false;
+                        
+            // Only intercept the track once
+            if (track_intercept)
+                return false;
+            
+            track_intercept = true;
+            
+            // Add the track when it has come from a different source
+            if (ServiceManager.SourceManager.ActiveSource != this) {
+                // Add the track to the play queue
+                if(ServiceManager.SourceManager.ActiveSource != this)
+                    this.EnqueueTrack(track, false);
+                
+                // keep the source as the play queue
+                ServiceManager.PlaybackController.Source = this;
+                //ServiceManager.SourceManager.SetActiveSource(this);                
+            }
+
+            if (ServiceManager.PlayerEngine.IsPlaying() == false && Count > 0)
+                ServiceManager.PlayerEngine.Play();
+            
+            track_intercept = false;
+            
+            return true;
+       
+        }
+        
         private void SetAsPlaybackSourceUnlessPlaying ()
         {
             if (Count > 0 && ServiceManager.PlaybackController.Source != this) {
@@ -165,9 +214,12 @@
 
         public void Clear ()
         {
-            playing_track = null;
-            RemoveTrackRange (DatabaseTrackModel, new Hyena.Collections.RangeCollection.Range (0, Count));
-            Reload ();
+            if(!is_party_mode)
+            {
+                playing_track = null;
+                RemoveTrackRange (DatabaseTrackModel, new Hyena.Collections.RangeCollection.Range (0, Count));
+                Reload ();
+            }
         }
 
         public void Dispose ()
@@ -216,13 +268,7 @@
         private void OnPlayerEvent (PlayerEventArgs args)
         {
             if (args.Event == PlayerEvent.EndOfStream) {
-                if (RemovePlayingTrack () && Count == 0) {
-                    if (was_playing) {
-                        ServiceManager.PlaybackController.PriorTrack = prior_playback_track;
-                    } else {
-                        ServiceManager.PlaybackController.StopWhenFinished = true;
-                    }
-                }
+                ServiceManager.PlaybackController.Next (true);
             } else if (args.Event == PlayerEvent.StartOfStream) {
                 if (this == ServiceManager.PlaybackController.Source) {
                     playing_track = ServiceManager.PlayerEngine.CurrentTrack as DatabaseTrackInfo;
@@ -232,7 +278,106 @@
                 }
             }
         }
+        
+        public void AddRandomTracks(int count)
+        {
+            
+            // Get 5 random tracks 
+            // Attributes restricted tracks to music only
+            IEnumerable<int> tracks = ServiceManager.DbConnection.QueryEnumerable<int> ("SELECT TrackId FROM CoreTracks WHERE Attributes & 4 == 4 AND Attributes & 2 == 0 ORDER BY Random() LIMIT ?", count);
 
+            // Add to queue
+            foreach(int trackId in tracks) {
+                EnqueueId(trackId, false);
+            }    
+        }
+
+        public bool IsPartyMode
+        {
+            get {return is_party_mode;}
+            set 
+            {
+                
+                GtkElementsService service = ServiceManager.Get<GtkElementsService> ();
+                if (service == null) {
+                    return;
+                }
+                
+                is_party_mode = value;  
+                      
+                // Full screen mode
+                Gtk.Window window = service.PrimaryWindow;
+                if (window != null) {
+                    if (is_party_mode) 
+                        window.Fullscreen ();
+                    else
+                        window.Unfullscreen ();
+                }
+                                
+                // retrieve and hide the gtk menu
+                Gtk.MenuShell menu = (Gtk.MenuShell) uia_service.UIManager.GetWidget ("/MainMenu");
+                if(menu != null) {
+                    if(is_party_mode)
+                        menu.Hide ();
+                    else
+                        menu.Show ();
+                }
+                
+                // retrieve and hide the gtk toolbar
+                Gtk.Toolbar toolbar = (Gtk.Toolbar) uia_service.UIManager.GetWidget ("/HeaderToolbar");
+                if (toolbar != null) {
+                    if(is_party_mode)
+                        toolbar.Hide ();
+                    else
+                        toolbar.Show ();
+                }
+                                                
+                Reload ();
+                
+            }
+        }
+        
+            
+        private void TrackActionPreActivate(object sender, Gtk.PreActivateArgs args)
+        {
+                       
+            Gtk.Action action = args.Action.ActionGroup.GetAction("RemoveTracksAction");  
+            if(action != null)
+                action.Visible = !is_party_mode;
+            
+            action = args.Action.ActionGroup.GetAction("TrackEditorAction");  
+            if(action != null)
+                action.Visible = !is_party_mode;
+ 
+            action = args.Action.ActionGroup.GetAction("RemoveTracksFromLibraryAction");  
+            if(action != null && action.Visible)
+                action.Visible = !is_party_mode;
+            
+            action = args.Action.ActionGroup.GetAction("DeleteTracksFromDriveAction");  
+            if(action != null && action.Visible)
+                action.Visible = !is_party_mode;
+            
+            action = args.Action.ActionGroup.GetAction("AddToPlaylistAction");  
+            if(action != null && action.Visible)
+                action.Visible = !is_party_mode; 
+            
+            action = args.Action.ActionGroup.GetAction("BurnDiscAction");  
+            if(action != null && action.Visible)
+                action.Visible = !is_party_mode;
+            
+        }
+        
+        public override void ReorderSelectedTracks (int drop_row)
+        {
+            if (!(is_party_mode))
+                base.ReorderSelectedTracks (drop_row);
+        }
+      
+        public override bool AcceptsInputFromSource (Source source)
+        {
+            return base.AcceptsInputFromSource (source);
+        }
+ 
         bool IBasicPlaybackController.First ()
         {
             return ((IBasicPlaybackController)this).Next (false);
@@ -243,20 +388,26 @@
             RemovePlayingTrack ();
             
             if (Count == 0) {
-                ServiceManager.PlaybackController.Source = PriorSource;
-                if (was_playing) {
-                    ServiceManager.PlaybackController.PriorTrack = prior_playback_track;
-                    ServiceManager.PlaybackController.Next (restart);
-                } else {
-                    ServiceManager.PlayerEngine.Close ();
+                if (is_party_mode || AutoDJSchema.Get()) {
+                    AddRandomTracks(1);
+                    ServiceManager.PlaybackController.Next (false);
                 }
-                return true;
+                else {       
+                    ServiceManager.PlaybackController.Source = PriorSource;
+                    if (was_playing) {
+                        ServiceManager.PlaybackController.PriorTrack = prior_playback_track;
+                        ServiceManager.PlaybackController.Next (restart);
+                    } else {
+                        ServiceManager.PlayerEngine.Close ();
+                    }
+                    return true;
+                }
             }
             
             ServiceManager.PlayerEngine.OpenPlay ((DatabaseTrackInfo)TrackModel[0]);
             return true;
         }
-        
+                
         bool IBasicPlaybackController.Previous (bool restart)
         {
             return true;
@@ -304,11 +455,34 @@
             get { return false; }
         }
         
+        public override bool CanRemoveTracks {
+            get { return !is_party_mode;  }
+        }
+
+        public override bool CanSearch {
+            get { return false; }
+        }
+        
         public static readonly SchemaEntry<bool> ClearOnQuitSchema = new SchemaEntry<bool> (
             "plugins.play_queue", "clear_on_quit",
             false,
             "Clear on Quit",
             "Clear the play queue when quitting"
         );
+        
+        public static readonly SchemaEntry<bool> AutoDJSchema = new SchemaEntry<bool> (
+            "plugins.play_queue", "auto_dj",
+            false,
+            "Auto DJ",
+            "Add extra tracks when queue is empty"
+        );
+        
+        public static readonly SchemaEntry<bool> PlayQueueModeSchema = new SchemaEntry<bool> (
+            "plugins.play_queue", "play_queue_mode",
+            false,
+            "Play Queue Mode",
+            "Play all tracks through the play queue"
+        );
+        
     }
 }
Index: src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs
===================================================================
--- src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs	(revision 4875)
+++ src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs	(working copy)
@@ -255,7 +255,7 @@
             return false;
         }
         
-        public void ReorderSelectedTracks (int drop_row)
+        public virtual void ReorderSelectedTracks (int drop_row)
         {
             if (TrackModel.Selection.Count == 0 || TrackModel.Selection.AllSelected) {
                 return;

Attachment: Banshee.PlayQueue.tar.gz
Description: GNU Zip compressed data



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]