Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: How to skip tracks played during the last x hours? (Read 7110 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

How to skip tracks played during the last x hours?

I am quite happy with the current feature set of foobar and am using it regularly as a "killer-app" jukebox. However, there is one thing left constantly bothering me: We are operating foobar with multiple users for long hours, and different people constantly put in the tracks they'd like to hear. This results in the embarrassing and by now well-known complaint "Hey, you just played this track!". The solution is obvious, but I was unable to figure out how to do it:

How to make foobar skip a track if it was played during the last x hours?

I've read a lot about workarounds like autoplaylists, outdated components (foo_cwb_hooks) and so on. But with recent foobar versions, it just doesn't seem to solve the problem.

Here's the workaround I'm currently using at least for visual confirmation:
1. Define the constant variables xday/xmonth/xyear via the component "extended variables", restart foobar (doh!)
2. Mark the already played tracks by dimming them in the playlist (DUI): $ifgreater($day_of_month(%last_played%),%xday%,$ifequal($month(%last_played%),%xmonth%,$ifequal($year(%last_played%),%xyear%,>>>,),),)

The problems are:
a) It doesn't work for HOURS, just for DAYS (ideal would be 'skip if played during the last 4 hours' or so) *
b) It doesn't work over midnights (yes, this is important for evening events), for last day of month of new year's eve
d) It integrate with foo_skip and cannot auto-skip tracks

* Edit: I also tried to put a unix timestamp in a global variable and to compare that directly to ADDED_TIMESTAMP to make hour/minute/... comparison work, but was unable to generate timestamps that looked like or allowed comparison to the foobar timestamps. If I'd at least get that to work I'd be happy, too.

Any ideas anyone? If not it would make a nice feature to implement in one of the upcoming versions, doesn't sound that metaphysical or feature-overloaded to me, but then again I'm not the developer... and as far as I've read, even for third-party components to address this issue, at least a global time variable would have to be introduced in the core (?)

How to skip tracks played during the last x hours?

Reply #1
Autoplaylist with (NOT %last_played% DURING LAST x HOURS)
Then only allow to search and play from the autoplaylist?

You'd need foo_playcount.

C.
PC = TAK + LossyWAV  ::  Portable = Opus (130)

How to skip tracks played during the last x hours?

Reply #2
Autoplaylist with (NOT %last_played% DURING LAST x HOURS)
Then only allow to search and play from the autoplaylist?


Well, that's one of the workarounds that I've already read of. But that really isn't the thing I'm looking for:
* it would be still possible to add a track that's already in the playlist, but hasn't played yet
* all the power of the library viewer (trees, multiple views) would be lost, which is not an option with large collections
* it's not nearly as usable as automatic skipping of tracks in the current playlist would be...

... the additional problem is that some of my colleagues are challenged enough to drag'n drop files from the library to the playlist as it is, so explaining about autoplaylists and "search here not there" would just result in the comment "Your fancy foobar stuff is all good and well, but all things considered, but let's just use winamp or windows media player". And I'm one of the foobar users that doesn't wish this program to be only usable for the elite select few.

PS: I've got foo_playcount, or otherwise my $day_of_month() fix would be useless.

How to skip tracks played during the last x hours?

Reply #3
One more thing: To really make this work it would be necessary to do a database search for artist/title like the current foo_playcount does for the ratings, or even with a simple auto-skip mechanism it would still be possible to hear numerous slightly different encodings of the same song. But of course that's only perfectionism, It would be absolutely sufficient to just make auto-skipping work for the same files.

How to skip tracks played during the last x hours?

Reply #4
Yes, I see.

Ideally you'd want a (non auto-) playlist that had self-filtering properties based on %last_played% criteria.

Something like foo_dynfil would be ideal to create a field based on a range of last played criteria, called %_dont_play_again%.
Then if foo_playlist_attributes could have a "self-managing queue" that said:

IF %_dont_play_again% = YES then remove from playlist OTHERWISE leave it alone.

That way, if the song appears twice in the queue, then when it's played the other instance is also removed.

Additionally people could pick songs from the library regardless, because the filtering would happen after selection.
At present it seems that you are trying to filter pre-selection.

Just thoughts, but I'd contact the foo_playlist_attributes developer and request the above functionality, i.e. remove tracks based on %FIELD% criteria. It may already be possible, not sure.

But certainly I'd have thought you're better off filtering post-selection rather than pre-selection.

Cheers,

C.

ps. Actually, can't you do this with skip, i.e. if %_dont_play_again% = YES then %skip% = 1 OTHERWISE %skip% = 0.
EDIT: Ah, but foo_skip has to write to the file tags which is far from ideal, even if it could be done.
PC = TAK + LossyWAV  ::  Portable = Opus (130)

How to skip tracks played during the last x hours?

Reply #5
Solved (I think):

You need:

foo_skip
foo_playcount
foo_dynfil

1) Install
2) Preferences > Dynamic Fields > add (+) > ENTER: "dontplayagain" (without quotes)
3) Paste the following code (this is for one hour, it's in seconds):
Code: [Select]
$ifgreater($time_diff(%last_played%),3599,0,1)

4) Preferences > Advanced > Playback > Skip Tracks >

- Skip Track Query = "%_dontplayagain% IS 1" (without quotes)
- Tick "Skip even manually selected tracks"

DONE.

Try that, I've just tested it and it worked for me.
Obviously you'll want to change the:
$ifgreater($time_diff(%last_played%),3599,0,1)
time to however many hours you want to allow the ban to last.

Perhaps 5 hours (i.e., 17999).

Cheers,

C.

EDIT: By the way you may also want foo_playlist_attributes and set the playlist's (where the selections end up) attributes to "remove skipped tracks".
PC = TAK + LossyWAV  ::  Portable = Opus (130)

How to skip tracks played during the last x hours?

Reply #6
Thanks for your comments on this, I haven't given up hope yet! :-)

Something like foo_dynfil would be ideal to create a field based on a range of last played criteria, called %_dont_play_again%.

I didn't know that one yet and will have a look at it.

Quote
Ideally you'd want a (non auto-) playlist that had self-filtering properties based on %last_played% criteria.

I agree that 'post-selection' is the way to go, thus retaining the well-known workflow for users.

As far as I understand it, you're proposing two options - #1:

Quote
IF %_dont_play_again% = YES then remove from playlist OTHERWISE leave it alone. That way, if the song appears twice in the queue, then when it's played the other instance is also removed. (...) Just thoughts, but I'd contact the foo_playlist_attributes developer and request the above functionality, i.e. remove tracks based on %FIELD% criteria. It may already be possible, not sure.

Everything would be fine by me if it would work somehow. However,
* important: with this option, if you add a song to the playlist that has already been played during the given timeframe the mechanism wouldn't work because the 'trigger' (i.e. playing the first duplicate) is missing.
* not such a big concern, but worth mentioning: on the 'social' level the deferred removal option wouldn't be my preferred one, because people might wonder what happened ("Hey, you kicked out my song behind my back!"). If it was only skipped (and 'remove skipped' is off, 'remove played' on) it would still be visible on top of the list.

So my vote would still be for #2:

Quote
ps. Actually, can't you do this with skip, i.e. if %_dont_play_again% = YES then %skip% = 1 OTHERWISE %skip% = 0.
EDIT: Ah, but foo_skip has to write to the file tags which is far from ideal, even if it could be done.

I fear you're correct, foo_skip can only use static file-tags and thus wouldn't work for this purpose. Maybe someone else can come up with something similar, because if there was a way to *skip* (and not remove) tracks by %_dont_play_again_% users would still see 'their' song in the playlist, but it could be *immediately* (and not only when the first duplication is played) marked somehow to make clear that is won't play or hasn't played because of duplication.

How to skip tracks played during the last x hours?

Reply #7
Solved (I think):


You were faster than my last reply ... Thanks, I'll try that tomorrow, if it works out your're a genius because many people in the forum have been trying to get this very thing to work!


How to skip tracks played during the last x hours?

Reply #8
See above solution.

One final thing, in foo_dynfil you'd want to choose a decent recalculation rate, like 1 hour, so it may go like this (not sure), but say you want to stop songs being played again for 6 hours, then maybe do the 18000 seconds (5 hours) and then choose to recalc every 1 hour (5 + 1 = 6). You'll have to experiment.

C.

EDIT: Additionally, this may be more handy, if you set foo_dynfil to NEVER recalculate, then I think regardless of that value you put in the code, it will never replay a song during a foobar2000 instance, so from when you start fb2k it will never repeat a track. That may or may not be preferable.

EDIT2:
To notify users:
Code: [Select]
$ifgreater(%_dontplayagain%,0,'BAN: Recently Played',)
PC = TAK + LossyWAV  ::  Portable = Opus (130)

How to skip tracks played during the last x hours?

Reply #9
After a little testing, this is a better bit of code for foo_dynfil:

Code: [Select]
$puts(skip,$ifgreater($time_diff(%last_played%),3599,0,1))
$ifgreater(%play_count%,0,$get(skip),0)

There was a minor issue with tracks that hadn't yet been played being skipped. This solves that and makes sure Playcount = 0 gets a skip value of 0 rather than 1.

Additionally, if you use Gapless Crossfader (or perhaps other DSPs) you need to add Skip Track as the final DSP in:
Preferences > Playback > DSP Manager.

If you add it (as I did) while a track is playing you may get the remainder of the track playing silently, but after that all is fine.

C.
PC = TAK + LossyWAV  ::  Portable = Opus (130)

How to skip tracks played during the last x hours?

Reply #10
After a little testing, this is a better bit of code for foo_dynfi


Many thanks again! The only shortcomings are that
* it doesn't work for files outside the media library, but this isn't what foo_dynfil was made for.
* it only works for exactly the same files (and doesn't implement the db approach mentioned above).

But it's working at last, this is a great help.



How to skip tracks played during the last x hours?

Reply #13
... I'd just like to share another thing I had to figure out:

foo_skip has to be the first DSP in the chain (or crossfading doesn't work at all), and if you're using "gapless crossfader" you have to switch "gapless" mode off (or there is a short pause when a track is skipped).

How to skip tracks played during the last x hours?

Reply #14
From here: http://www.saunalahti.fi/~cse/foobar2000/?changes=foo_skip
Quote
1.0 (2010-05-02): Previous version broke gapless playback. Simplified the DSP code. Skip Track should be the last DSP in the chain.

That said, I've experienced the same even with it at the end. Be nice to know which is correct.

C.
PC = TAK + LossyWAV  ::  Portable = Opus (130)