I just posted my final track for this year’s #looptober, and as a little bonus, I made a page that lets you play all the finished loops.
And since each loop is also a fediverse post, I played a bit with the presentation. Here’s a quick walkthrough how I made the fediverse audio player wall.
First, let’s define the structure of the grid. My site uses the Bootstrap library, so I made a simple grid using its classes.
<div class="container break-out bg-light mt-5 mb-5 p-5 pt-5 pb-5">
<div class="row">
<div class="col-sm-12 col-md-6 col-lg-4 col-xl-3 p-2 pt-3 pb-3">
<div class="player-card card border border-0">
<div class="card-body">
<p>
<strong>
<a
href="POST_URL"
target="_blank"
rel="noopener"
>LABEL</a>
</strong>
<span
class="fediverse-post-stats badge rounded-pill text-bg-dark fs-6 float-end"
data-instance="FEDIVERSE_INSTANCE"
data-post-id="POST_ID"
></span>
</p>
<audio controls loop class="w-100 mb-3">
<source
src="DOWNLOAD_URL"
type="audio/mpeg"
/>
</audio>
</div>
</div>
</div>
<!-- ... -->
</div>
</div>
You will need to repeat the <div class="col-sm-12
section for each one of your audio posts. You could, of course, create the grid fully with JavaScript, or if you can use a back-end template, that works well too.
Looking closer at the paragraph inside the card-body element, you will notice a few placeholder values.
POST_URL
: this is the URL of your postLABEL
: short text that will appear above the audio player, in my case I used the dateFEDIVERSE_INSTANCE
: the name of your instance, for examplemastodon.social
, or in my casestefanbohacek.online
POST_ID
: the ID of the post, or the number at the ofPOST_URL
DOWNLOAD_URL
: let me show you how to get this
Let me use my first loop as an example. The post is from a Mastodon server, so if you use a different platform, instructions might differ slightly, but should follow the same principles.
The link to the post is https://stefanbohacek.online/@stefan/111188071612023386
. The value for FEDIVERSE_INSTANCE
will be stefanbohacek.online
and the POST_ID
is 111188071612023386
.
And finally, you can find the download URL by right-clicking the download icon and selecting the “Copy link address” menu item (or a similar one based on the browser you’re using).
And there you have it, this is what the finished block of HTML will look like.
<div class="col-sm-12 col-md-6 col-lg-4 col-xl-3 p-2 pt-3 pb-3">
<div class="player-card card border border-0">
<div class="card-body">
<p>
<strong>
<a
href="https://stefanbohacek.online/@stefan/111188071612023386"
target="_blank"
rel="noopener"
>LABEL</a>
</strong>
<span
class="fediverse-post-stats badge rounded-pill text-bg-dark fs-6 float-end"
data-instance="stefanbohacek.online"
data-post-id="111188071612023386"
></span>
</p>
<audio controls loop class="w-100 mb-3">
<source
src="https://stefanbohacek.online/system/media_attachments/files/111/188/061/387/973/533/original/820ccf2d4eb89c75.mp3"
type="audio/mpeg"
/>
</audio>
</div>
</div>
</div>
You can repeat this section for each of your audio player posts. Now comes the fun part of getting the number of likes, reposts, and comments. (You can of course skip this part if you don’t care about such nonsense.)
The details depend on the platform you’re using, here’s what worked for me on Mastodon using the statuses
API endpoint.
[
...document.getElementsByClassName(
"fediverse-post-stats"
),
].forEach(async (el) => {
const instance = el.dataset.instance;
const postId = el.dataset.postId;
if (postId) {
const response = await fetch(`https://${instance}/api/v1/statuses/${postId}`);
const data = await response.json();
console.log(data);
el.innerHTML = `
<a
class="text-decoration-none"
href="${data.url}"
>
❤️ ${data.favourites_count}
🔁 ${data.reblogs_count}
💬 ${data.replies_count}
</a>
`;
}
});
One last thing I did was to add a little snippet of code that will pause the loop when a you start another one.
document.addEventListener(
"play",
(e) => {
const audios = document.getElementsByTagName("audio");
for (let i = 0, len = audios.length; i < len; i++) {
if (audios[i] != e.target) {
audios[i].pause();
}
}
},
true
);
And we’re done! Hope you found this useful, and feel free to share your audio post walls with me!