diff --git a/api/funkwhale_api/federation/serializers.py b/api/funkwhale_api/federation/serializers.py
index 977ab0bb1dddd0363d02c5be389dce28b91444b2..76c2514698b4319a6b01642a695745c2a587a1fe 100644
--- a/api/funkwhale_api/federation/serializers.py
+++ b/api/funkwhale_api/federation/serializers.py
@@ -204,6 +204,7 @@ class APIActorSerializer(serializers.ModelSerializer):
             "type",
             "manually_approves_followers",
             "full_username",
+            "is_local",
         ]
 
 
diff --git a/api/funkwhale_api/radios/radios.py b/api/funkwhale_api/radios/radios.py
index 01a242216085e799cfef1ae8a29765f448d2aee1..08329c6ead3ec09761864beeecede740911fa8b4 100644
--- a/api/funkwhale_api/radios/radios.py
+++ b/api/funkwhale_api/radios/radios.py
@@ -5,10 +5,11 @@ from django.db import connection
 from django.db.models import Q
 from rest_framework import serializers
 
+from funkwhale_api.federation import models as federation_models
+from funkwhale_api.federation import fields as federation_fields
 from funkwhale_api.moderation import filters as moderation_filters
-from funkwhale_api.music.models import Artist, Track
+from funkwhale_api.music.models import Artist, Library, Track, Upload
 from funkwhale_api.tags.models import Tag
-
 from . import filters, models
 from .registries import registry
 
@@ -271,3 +272,47 @@ class LessListenedRadio(SessionRadio):
         qs = super().get_queryset(**kwargs)
         listened = self.session.user.listenings.all().values_list("track", flat=True)
         return qs.exclude(pk__in=listened).order_by("?")
+
+
+@registry.register(name="actor_content")
+class ActorContentRadio(RelatedObjectRadio):
+    """
+    Play content from given actor libraries
+    """
+
+    model = federation_models.Actor
+    related_object_field = federation_fields.ActorRelatedField(required=True)
+
+    def get_related_object(self, value):
+        return value
+
+    def get_queryset(self, **kwargs):
+        qs = super().get_queryset(**kwargs)
+        actor_uploads = Upload.objects.filter(
+            library__actor=self.session.related_object,
+        )
+        return qs.filter(pk__in=actor_uploads.values("track"))
+
+    def get_related_object_id_repr(self, obj):
+        return obj.full_username
+
+
+@registry.register(name="library")
+class LibraryRadio(RelatedObjectRadio):
+    """
+    Play content from a given library
+    """
+
+    model = Library
+    related_object_field = serializers.UUIDField(required=True)
+
+    def get_related_object(self, value):
+        return Library.objects.get(uuid=value)
+
+    def get_queryset(self, **kwargs):
+        qs = super().get_queryset(**kwargs)
+        actor_uploads = Upload.objects.filter(library=self.session.related_object,)
+        return qs.filter(pk__in=actor_uploads.values("track"))
+
+    def get_related_object_id_repr(self, obj):
+        return obj.uuid
diff --git a/api/tests/radios/test_radios.py b/api/tests/radios/test_radios.py
index 2aa60c36a9ac54a08773d0343fedcbc96d21272b..38a1ac831eb1af6b0a5668a9571debe0aace2b3a 100644
--- a/api/tests/radios/test_radios.py
+++ b/api/tests/radios/test_radios.py
@@ -47,6 +47,28 @@ def test_can_pick_by_weight():
     assert picks[2] > picks[1]
 
 
+def test_session_radio_excludes_previous_picks(factories):
+    tracks = factories["music.Track"].create_batch(5)
+    user = factories["users.User"]()
+    previous_choices = []
+    for i in range(5):
+        TrackFavorite.add(track=random.choice(tracks), user=user)
+
+    radio = radios.SessionRadio()
+    radio.radio_type = "favorites"
+    radio.start_session(user)
+
+    for i in range(5):
+        pick = radio.pick(user=user, filter_playable=False)
+        assert pick in tracks
+        assert pick not in previous_choices
+        previous_choices.append(pick)
+
+    with pytest.raises(ValueError):
+        # no more picks available
+        radio.pick(user=user, filter_playable=False)
+
+
 def test_can_get_choices_for_favorites_radio(factories):
     files = factories["music.Upload"].create_batch(10)
     tracks = [f.track for f in files]
@@ -213,6 +235,77 @@ def test_can_start_tag_radio(factories):
         assert radio.pick(filter_playable=False) in good_tracks
 
 
+def test_can_start_actor_content_radio(factories):
+    actor_library = factories["music.Library"](actor__local=True)
+    good_tracks = [
+        factories["music.Upload"](playable=True, library=actor_library).track,
+        factories["music.Upload"](playable=True, library=actor_library).track,
+        factories["music.Upload"](playable=True, library=actor_library).track,
+    ]
+    factories["music.Upload"].create_batch(3, playable=True)
+
+    radio = radios.ActorContentRadio()
+    session = radio.start_session(
+        actor_library.actor.user, related_object=actor_library.actor
+    )
+    assert session.radio_type == "actor_content"
+
+    for i in range(3):
+        assert radio.pick() in good_tracks
+
+
+def test_can_start_actor_content_radio_from_api(
+    logged_in_api_client, preferences, factories
+):
+    actor = factories["federation.Actor"]()
+    url = reverse("api:v1:radios:sessions-list")
+
+    response = logged_in_api_client.post(
+        url, {"radio_type": "actor_content", "related_object_id": actor.full_username}
+    )
+
+    assert response.status_code == 201
+
+    session = models.RadioSession.objects.latest("id")
+
+    assert session.radio_type == "actor_content"
+    assert session.related_object == actor
+
+
+def test_can_start_library_radio(factories):
+    user = factories["users.User"]()
+    library = factories["music.Library"]()
+    good_tracks = [
+        factories["music.Upload"](library=library).track,
+        factories["music.Upload"](library=library).track,
+        factories["music.Upload"](library=library).track,
+    ]
+    factories["music.Upload"].create_batch(3)
+
+    radio = radios.LibraryRadio()
+    session = radio.start_session(user, related_object=library)
+    assert session.radio_type == "library"
+
+    for i in range(3):
+        assert radio.pick(filter_playable=False) in good_tracks
+
+
+def test_can_start_library_radio_from_api(logged_in_api_client, preferences, factories):
+    library = factories["music.Library"]()
+    url = reverse("api:v1:radios:sessions-list")
+
+    response = logged_in_api_client.post(
+        url, {"radio_type": "library", "related_object_id": library.uuid}
+    )
+
+    assert response.status_code == 201
+
+    session = models.RadioSession.objects.latest("id")
+
+    assert session.radio_type == "library"
+    assert session.related_object == library
+
+
 def test_can_start_artist_radio_from_api(logged_in_api_client, preferences, factories):
     artist = factories["music.Artist"]()
     url = reverse("api:v1:radios:sessions-list")
diff --git a/changes/changelog.d/radio.enhancement b/changes/changelog.d/radio.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..a46a9cd92be55908debdfed26e52f77c874de384
--- /dev/null
+++ b/changes/changelog.d/radio.enhancement
@@ -0,0 +1 @@
+Added two new radios to play your own content or a given library tracks
diff --git a/front/src/components/federation/LibraryWidget.vue b/front/src/components/federation/LibraryWidget.vue
index 7d24180879a70222cfefd18d4789953270af0f22..3bdc5208937819ff97d851be32476db1bcd65522 100644
--- a/front/src/components/federation/LibraryWidget.vue
+++ b/front/src/components/federation/LibraryWidget.vue
@@ -16,7 +16,7 @@
       </div>
       <library-card
         :display-scan="false"
-        :display-follow="$store.state.auth.authenticated"
+        :display-follow="$store.state.auth.authenticated && library.actor.full_username != $store.state.auth.fullUsername"
         :library="library"
         :display-copy-fid="true"
         v-for="library in libraries"
@@ -48,16 +48,16 @@ export default {
     }
   },
   created () {
-    this.fetchData()
+    this.fetchData(this.url)
   },
   methods: {
-    fetchData () {
+    fetchData (url) {
       this.isLoading = true
       let self = this
       let params = _.clone({})
       params.page_size = this.limit
       params.offset = this.offset
-      axios.get(this.url, {params: params}).then((response) => {
+      axios.get(url, {params: params}).then((response) => {
         self.previousPage = response.data.previous
         self.nextPage = response.data.next
         self.isLoading = false
diff --git a/front/src/components/library/Radios.vue b/front/src/components/library/Radios.vue
index b03801d807bc7fc164681345d319a483240315a4..fcc14b807efae7fc764870cc525152f76be6f30f 100644
--- a/front/src/components/library/Radios.vue
+++ b/front/src/components/library/Radios.vue
@@ -10,6 +10,7 @@
           <translate translate-context="Content/Radio/Title">Instance radios</translate>
         </h3>
         <div class="ui cards">
+          <radio-card v-if="isAuthenticated" :type="'actor_content'" :object-id="$store.state.auth.fullUsername"></radio-card>
           <radio-card v-if="isAuthenticated && hasFavorites" :type="'favorites'"></radio-card>
           <radio-card :type="'random'"></radio-card>
           <radio-card v-if="$store.state.auth.authenticated" :type="'less-listened'"></radio-card>
diff --git a/front/src/components/radios/Card.vue b/front/src/components/radios/Card.vue
index e72b9f1c1ca65cf6fd10020fe1b0b720de5a49f9..55ccb4005616d8795b2153edf579366d1b4dca51 100644
--- a/front/src/components/radios/Card.vue
+++ b/front/src/components/radios/Card.vue
@@ -16,7 +16,7 @@
       <div class="extra content">
         <user-link v-if="radio.user" :user="radio.user" class="left floated" />
         <div class="ui hidden divider"></div>
-        <radio-button class="right floated button" :type="type" :custom-radio-id="customRadioId"></radio-button>
+        <radio-button class="right floated button" :type="type" :custom-radio-id="customRadioId" :object-id="objectId"></radio-button>
         <router-link
           class="ui basic yellow button right floated"
           v-if="$store.state.auth.authenticated && type === 'custom' && radio.user.id === $store.state.auth.profile.id"
@@ -33,7 +33,8 @@ import RadioButton from './Button'
 export default {
   props: {
     type: {type: String, required: true},
-    customRadio: {required: false}
+    customRadio: {required: false},
+    objectId: {required: false},
   },
   components: {
     RadioButton
diff --git a/front/src/store/radios.js b/front/src/store/radios.js
index c27421ed06ca4fbbd6b8c0926c226e7099550165..6eb06566ff21b7533c840e4c0c9974ae551ab8f3 100644
--- a/front/src/store/radios.js
+++ b/front/src/store/radios.js
@@ -10,6 +10,10 @@ export default {
   getters: {
     types: state => {
       return {
+        actor_content: {
+          name: 'Your content',
+          description: "Picks from your own libraries"
+        },
         random: {
           name: 'Random',
           description: "Totally random picks, maybe you'll discover new things?"
diff --git a/front/src/views/content/libraries/DetailArea.vue b/front/src/views/content/libraries/DetailArea.vue
index 0a73c90b927589c55bd1353a399febd67bb2309e..62928c05c1123bb2413047f01807275849e0fcbb 100644
--- a/front/src/views/content/libraries/DetailArea.vue
+++ b/front/src/views/content/libraries/DetailArea.vue
@@ -4,6 +4,7 @@
       <div class="column">
         <h3 class="ui header"><translate translate-context="Content/Library/Title">Current library</translate></h3>
         <library-card :library="library" />
+        <radio-button :type="'library'" :object-id="library.uuid"></radio-button>
       </div>
     </div>
     <div class="ui hidden divider"></div>
@@ -12,12 +13,14 @@
 </template>
 
 <script>
+import RadioButton from '@/components/radios/Button'
 import LibraryCard from './Card'
 
 export default {
   props: ['library'],
   components: {
-    LibraryCard
+    LibraryCard,
+    RadioButton,
   },
   computed: {
     links () {
diff --git a/front/src/views/content/remote/Card.vue b/front/src/views/content/remote/Card.vue
index d87b7f3b45231b0cddb08cd4984030ea183e3b66..1676c073b82457ce390866712ffedba1539f4fb3 100644
--- a/front/src/views/content/remote/Card.vue
+++ b/front/src/views/content/remote/Card.vue
@@ -93,40 +93,39 @@
         </div>
       </div>
     </div>
-    <div v-if="displayFollow" :class="['ui', 'bottom', {two: library.follow}, 'attached', 'buttons']">
-      <button
-        v-if="!library.follow"
-        @click="follow()"
-        :class="['ui', 'green', {'loading': isLoadingFollow}, 'button']">
-        <translate translate-context="Content/Library/Card.Button.Label/Verb">Follow</translate>
-      </button>
-      <template v-else-if="!library.follow.approved">
+    <div v-if="displayFollow || radioPlayable" :class="['ui', {two: displayFollow && radioPlayable}, 'bottom', 'attached', 'buttons']">
+      <radio-button v-if="radioPlayable" :type="'library'" :object-id="library.uuid"></radio-button>
+      <template v-if="displayFollow">
         <button
-          class="ui disabled button"><i class="hourglass icon"></i>
-          <translate translate-context="Content/Library/Card.Paragraph">Follow request pending approval</translate>
+          v-if="!library.follow"
+          @click="follow()"
+          :class="['ui', 'green', {'loading': isLoadingFollow}, 'button']">
+          <translate translate-context="Content/Library/Card.Button.Label/Verb">Follow</translate>
         </button>
-        <button
-          @click="unfollow"
-          class="ui button">
-          <translate translate-context="Content/Library/Card.Paragraph">Cancel follow request</translate>
-        </button>
-      </template>
-      <template v-else-if="library.follow.approved">
-        <button
-          class="ui disabled button"><i class="check icon"></i>
-          <translate translate-context="Content/Library/Card.Paragraph">Following</translate>
-        </button>
-        <dangerous-button
-          color=""
-          :class="['ui', 'button']"
-          :action="unfollow">
-          <translate translate-context="*/Library/Button.Label/Verb">Unfollow</translate>
-          <p slot="modal-header"><translate translate-context="Popup/Library/Title">Unfollow this library?</translate></p>
-          <div slot="modal-content">
-            <p><translate translate-context="Popup/Library/Paragraph">By unfollowing this library, you loose access to its content.</translate></p>
-          </div>
-          <div slot="modal-confirm"><translate translate-context="*/Library/Button.Label/Verb">Unfollow</translate></div>
-        </dangerous-button>
+        <template v-else-if="!library.follow.approved">
+          <button
+            class="ui disabled button"><i class="hourglass icon"></i>
+            <translate translate-context="Content/Library/Card.Paragraph">Follow request pending approval</translate>
+          </button>
+          <button
+            @click="unfollow"
+            class="ui button">
+            <translate translate-context="Content/Library/Card.Paragraph">Cancel follow request</translate>
+          </button>
+        </template>
+        <template v-else-if="library.follow.approved">
+          <dangerous-button
+            color=""
+            :class="['ui', 'button']"
+            :action="unfollow">
+            <translate translate-context="*/Library/Button.Label/Verb">Unfollow</translate>
+            <p slot="modal-header"><translate translate-context="Popup/Library/Title">Unfollow this library?</translate></p>
+            <div slot="modal-content">
+              <p><translate translate-context="Popup/Library/Paragraph">By unfollowing this library, you loose access to its content.</translate></p>
+            </div>
+            <div slot="modal-confirm"><translate translate-context="*/Library/Button.Label/Verb">Unfollow</translate></div>
+          </dangerous-button>
+        </template>
       </template>
     </div>
   </div>
@@ -134,6 +133,7 @@
 <script>
 import axios from 'axios'
 import ReportMixin from '@/components/mixins/Report'
+import RadioButton from '@/components/radios/Button'
 import jQuery from 'jquery'
 
 export default {
@@ -144,6 +144,9 @@ export default {
     displayScan: {type: Boolean, default: true},
     displayCopyFid: {type: Boolean, default: true},
   },
+  components: {
+    RadioButton
+  },
   data () {
     return {
       isLoadingFollow: false,
@@ -195,7 +198,13 @@ export default {
         return false
       }
       return true
-    }
+    },
+    radioPlayable () {
+      return (
+        (this.library.actor.is_local || this.scanStatus === 'finished') &&
+        (this.library.privacy_level === 'everyone' || (this.library.follow && this.library.follow.is_approved))
+      )
+    },
   },
   methods: {
     launchScan () {