Skip to content

Commit

Permalink
Follow client setting to filter explicit tracks
Browse files Browse the repository at this point in the history
 - Don't load explicit tracks when the client setting forbids them

 - When a client switches explicit filtering on *while* playing
   an explicit track, immediately skip to the next track
  • Loading branch information
roderickvd committed Dec 30, 2021
1 parent 2af34fc commit 0fdff0d
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 0 deletions.
5 changes: 5 additions & 0 deletions connect/src/spirc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -746,12 +746,17 @@ impl SpircTask {
_ => old_value,
};
self.session.set_user_attribute(key, new_value);

trace!(
"Received attribute mutation, {} was {} is now {}",
key,
old_value,
new_value
);

if key == "filter-explicit-content" && new_value == "1" {
self.player.skip_explicit_content();
}
} else {
trace!(
"Received attribute mutation for {} but key was not found!",
Expand Down
1 change: 1 addition & 0 deletions metadata/src/audio/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub struct AudioItem {
pub duration: i32,
pub availability: AudioItemAvailability,
pub alternatives: Option<Tracks>,
pub is_explicit: bool,
}

impl AudioItem {
Expand Down
1 change: 1 addition & 0 deletions metadata/src/episode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ impl InnerAudioItem for Episode {
duration: episode.duration,
availability,
alternatives: None,
is_explicit: episode.is_explicit,
})
}
}
Expand Down
1 change: 1 addition & 0 deletions metadata/src/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl InnerAudioItem for Track {
duration: track.duration,
availability,
alternatives,
is_explicit: track.is_explicit,
})
}
}
Expand Down
55 changes: 55 additions & 0 deletions playback/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ enum PlayerCommand {
SetSinkEventCallback(Option<SinkEventCallback>),
EmitVolumeSetEvent(u16),
SetAutoNormaliseAsAlbum(bool),
SkipExplicitContent(),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -456,6 +457,10 @@ impl Player {
pub fn set_auto_normalise_as_album(&self, setting: bool) {
self.command(PlayerCommand::SetAutoNormaliseAsAlbum(setting));
}

pub fn skip_explicit_content(&self) {
self.command(PlayerCommand::SkipExplicitContent());
}
}

impl Drop for Player {
Expand All @@ -478,6 +483,7 @@ struct PlayerLoadedTrackData {
bytes_per_second: usize,
duration_ms: u32,
stream_position_pcm: u64,
is_explicit: bool,
}

enum PlayerPreload {
Expand Down Expand Up @@ -513,6 +519,7 @@ enum PlayerState {
duration_ms: u32,
stream_position_pcm: u64,
suggested_to_preload_next_track: bool,
is_explicit: bool,
},
Playing {
track_id: SpotifyId,
Expand All @@ -526,6 +533,7 @@ enum PlayerState {
stream_position_pcm: u64,
reported_nominal_start_time: Option<Instant>,
suggested_to_preload_next_track: bool,
is_explicit: bool,
},
EndOfTrack {
track_id: SpotifyId,
Expand Down Expand Up @@ -608,6 +616,7 @@ impl PlayerState {
normalisation_data,
stream_loader_controller,
stream_position_pcm,
is_explicit,
..
} => {
*self = EndOfTrack {
Expand All @@ -620,6 +629,7 @@ impl PlayerState {
bytes_per_second,
duration_ms,
stream_position_pcm,
is_explicit,
},
};
}
Expand Down Expand Up @@ -648,6 +658,7 @@ impl PlayerState {
bytes_per_second,
stream_position_pcm,
suggested_to_preload_next_track,
is_explicit,
} => {
*self = Playing {
track_id,
Expand All @@ -661,6 +672,7 @@ impl PlayerState {
stream_position_pcm,
reported_nominal_start_time: None,
suggested_to_preload_next_track,
is_explicit,
};
}
_ => {
Expand Down Expand Up @@ -689,6 +701,7 @@ impl PlayerState {
stream_position_pcm,
reported_nominal_start_time: _,
suggested_to_preload_next_track,
is_explicit,
} => {
*self = Paused {
track_id,
Expand All @@ -701,6 +714,7 @@ impl PlayerState {
bytes_per_second,
stream_position_pcm,
suggested_to_preload_next_track,
is_explicit,
};
}
_ => {
Expand Down Expand Up @@ -778,6 +792,16 @@ impl PlayerTrackLoader {
audio.name, audio.spotify_uri
);

let is_explicit = audio.is_explicit;
if is_explicit {
if let Some(value) = self.session.get_user_attribute("filter-explicit-content") {
if &value == "1" {
warn!("Track is marked as explicit, which client setting forbids.");
return None;
}
}
}

let audio = match self.find_available_alternative(audio).await {
Some(audio) => audio,
None => {
Expand Down Expand Up @@ -951,6 +975,7 @@ impl PlayerTrackLoader {
bytes_per_second,
duration_ms,
stream_position_pcm,
is_explicit,
});
}
}
Expand Down Expand Up @@ -1518,6 +1543,7 @@ impl PlayerInternal {
Instant::now() - Duration::from_millis(position_ms as u64),
),
suggested_to_preload_next_track: false,
is_explicit: loaded_track.is_explicit,
};
} else {
self.ensure_sink_stopped(false);
Expand All @@ -1533,6 +1559,7 @@ impl PlayerInternal {
bytes_per_second: loaded_track.bytes_per_second,
stream_position_pcm: loaded_track.stream_position_pcm,
suggested_to_preload_next_track: false,
is_explicit: loaded_track.is_explicit,
};

self.send_event(PlayerEvent::Paused {
Expand Down Expand Up @@ -1674,6 +1701,7 @@ impl PlayerInternal {
bytes_per_second,
duration_ms,
normalisation_data,
is_explicit,
..
}
| PlayerState::Paused {
Expand All @@ -1683,6 +1711,7 @@ impl PlayerInternal {
bytes_per_second,
duration_ms,
normalisation_data,
is_explicit,
..
} = old_state
{
Expand All @@ -1693,6 +1722,7 @@ impl PlayerInternal {
bytes_per_second,
duration_ms,
stream_position_pcm,
is_explicit,
};

self.preload = PlayerPreload::None;
Expand Down Expand Up @@ -1943,6 +1973,30 @@ impl PlayerInternal {
PlayerCommand::SetAutoNormaliseAsAlbum(setting) => {
self.auto_normalise_as_album = setting
}

PlayerCommand::SkipExplicitContent() => {
if let PlayerState::Playing {
track_id,
play_request_id,
is_explicit,
..
}
| PlayerState::Paused {
track_id,
play_request_id,
is_explicit,
..
} = self.state
{
if is_explicit {
warn!("Currently loaded track is explicit, which client setting forbids -- skipping to next track.");
self.send_event(PlayerEvent::EndOfTrack {
track_id,
play_request_id,
})
}
}
}
};

Ok(result)
Expand Down Expand Up @@ -2080,6 +2134,7 @@ impl fmt::Debug for PlayerCommand {
.debug_tuple("SetAutoNormaliseAsAlbum")
.field(&setting)
.finish(),
PlayerCommand::SkipExplicitContent() => f.debug_tuple("SkipExplicitContent").finish(),
}
}
}
Expand Down

0 comments on commit 0fdff0d

Please sign in to comment.