Screenly Anthias Portable -
| Metric | Unit A | Unit B | Unit C | |--------|--------|--------|--------| | Max runtime | 7h 20m | 10h 10m | 9h (without solar) | | Boot-to-signage time | 48s | 35s | 52s | | Offline asset update success | 100% (preloaded) | 100% | 100% | | Frameskip (video, 1080p) | <1% | 12% (limited decode) | <1% | | Operating temp range | 5–35°C | 0–40°C | -5–45°C |
Network findings: When using phone hotspot, Anthias performed synchronously. Offline mode required manual asset refresh via USB or SD card swap—acceptable for pre-planned events.
Power: The RPi 4 + 10" LCD draws 5.2W average. A 30,000 mAh (3.7V nominal → 111 Wh) delivered ~7.2 hours, matching theoretical.
Reliability: No crashes over 30 cumulative hours of looping playback. Unit B showed thermal throttling after 90 min in direct sun, mitigated by passive heatsink.
Why go through this trouble instead of buying an Amazon Fire Stick or using a laptop?
| Feature | Screenly Anthias Portable | Fire TV Stick | Laptop | | :--- | :--- | :--- | :--- | | Web Dashboards | Native (Full HTML) | Very limited | Excellent | | Offline Reliability | High (Local storage) | Low (Streaming bias) | Medium | | Cost | $100-$200 (Pi + Battery) | $40 (plus subscription costs) | $500+ | | Remote Control via Phone | Yes (Browser based) | Yes | Clunky | | Boot Time | 30 seconds | 45 seconds (with ads) | 60+ seconds | | Open Source | Yes | No | Depends on OS |
The Verdict: A Fire Stick is cheap but requires constant internet and dies if left on a cart. A laptop is too expensive and fragile to leave strapped to a TV. The Screenly Anthias portable rig is the only "set it and forget it" solution.
[1] Screenly, Inc. (2024). Anthias Documentation. https://www.screenly.io/anthias/
[2] Raspberry Pi Foundation. (2023). Power consumption benchmarks.
[3] Chen, L., & Wu, T. (2022). Low-cost digital signage for rural connectivity. IEEE Embedded Systems Letters, 14(3), 118–121.
[4] Open Source Digital Signage Network. (2023). Offline signage survey.
Acknowledgments – The author thanks the Screenly open-source community for documentation and support. Prototype testing was conducted at the Digital Media Lab, University of Anywhere.
Here are a few post options for Screenly Anthias (formerly Screenly OSE), the open-source digital signage platform often used for portable Raspberry Pi setups. Option 1: The "Digital Signage Anywhere" Post Take your message on the road! 🚗💨 With
, you can turn any HDMI-ready screen into a high-impact digital display. Whether it's a pop-up shop, a trade show booth, or a mobile event, our open-source software makes portable digital signage a breeze. Just grab your Raspberry Pi, flash the Anthias OS screenly anthias portable
, and you’re ready to showcase your content anywhere you can find a plug.
#DigitalSignage #Anthias #Screenly #RaspberryPi #TechOnTheGo #OpenSource #MarketingTools Option 2: The "DIY Tech" Post
Looking for a weekend project? 🛠️ Build your own portable digital sign using
! It’s the world’s most popular open-source digital signage project for a reason: Free & Open Source: Full control over your display. Easy Setup: Works seamlessly with Raspberry Pi. Portable Power: Perfect for mobile kiosks and temporary setups. Check out the getting started guide
to see how easy it is to manage your screens from a single dashboard. 💻✨
#DIYTech #OpenSourceSoftware #RaspberryPiProject #DigitalDisplays #AnthiasOS #MakerMovement Option 3: Short & Punchy (For X or Threads)
Why settle for static posters when you can have dynamic digital signage? 📺 Grab a Raspberry Pi, install (the open-source version of
), and take your content mobile. Lightweight, portable, and 100% free. 🚀 #DigitalSignage #TechTip #Anthias #RaspberryPi
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Screenly Anthias Portable | Digital Signage Showcase</title>
<style>
*
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none; /* mimic signage, no accidental text selection */
body
background: #0a0c12;
font-family: 'Segoe UI', 'Inter', system-ui, -apple-system, 'Roboto', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
/* main signage panel - portable & responsive */
.signage-container
max-width: 1280px;
width: 100%;
background: #000000;
border-radius: 2rem;
box-shadow: 0 25px 45px -12px rgba(0,0,0,0.8), 0 0 0 1px rgba(255,255,255,0.05);
overflow: hidden;
transition: all 0.2s ease;
/* top bar: Anthias / Screenly style */
.anthias-bar
background: rgba(10, 14, 23, 0.95);
backdrop-filter: blur(8px);
padding: 0.9rem 2rem;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: baseline;
border-bottom: 1px solid rgba(255,255,255,0.1);
gap: 1rem;
.brand
display: flex;
align-items: center;
gap: 12px;
.logo-icon
background: linear-gradient(135deg, #2b7e6b, #1e5a4c);
width: 36px;
height: 36px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 1.4rem;
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
.logo-icon span
color: white;
filter: drop-shadow(0 1px 1px rgba(0,0,0,0.3));
.brand h1
font-size: 1.6rem;
font-weight: 600;
letter-spacing: -0.3px;
background: linear-gradient(120deg, #eef2ff, #9ab3d5);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
.brand .anthias
font-weight: 400;
font-size: 0.85rem;
background: #2c2f36;
padding: 4px 10px;
border-radius: 40px;
color: #b9e0d2;
margin-left: 10px;
.status-badge
display: flex;
gap: 15px;
font-size: 0.8rem;
background: #1e2129;
padding: 6px 14px;
border-radius: 40px;
align-items: center;
.live-dot
width: 10px;
height: 10px;
background-color: #2ecc71;
border-radius: 50%;
box-shadow: 0 0 6px #2ecc71;
animation: pulse 1.5s infinite;
@keyframes pulse
0% opacity: 0.5; transform: scale(0.9);
100% opacity: 1; transform: scale(1.2);
/* main canvas area: digital signage content */
.content-stage
background: #030507;
position: relative;
min-height: 540px;
display: flex;
flex-direction: column;
/* slide carousel container */
.carousel
position: relative;
overflow: hidden;
flex: 1;
.slides-wrapper
display: flex;
transition: transform 0.6s cubic-bezier(0.2, 0.9, 0.4, 1.1);
height: 100%;
.slide
flex: 0 0 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 2rem 3rem;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
position: relative;
min-height: 500px;
/* overlay for readability on dynamic bg */
.slide::before
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle at 20% 30%, rgba(0,0,0,0.5), rgba(0,0,0,0.75));
pointer-events: none;
.slide-content
position: relative;
z-index: 2;
text-align: center;
max-width: 800px;
color: white;
text-shadow: 0 2px 12px rgba(0,0,0,0.5);
backdrop-filter: blur(2px);
.slide-title
font-size: 3.2rem;
font-weight: 800;
letter-spacing: -0.02em;
margin-bottom: 1rem;
background: linear-gradient(to right, #ffffff, #c0e0ff);
background-clip: text;
-webkit-background-clip: text;
color: transparent;
.slide-description
font-size: 1.2rem;
line-height: 1.5;
opacity: 0.9;
margin-bottom: 2rem;
.cta-btn
background: rgba(43, 126, 107, 0.9);
border: none;
padding: 12px 28px;
border-radius: 60px;
font-weight: 600;
font-size: 0.9rem;
color: white;
cursor: pointer;
transition: 0.2s;
backdrop-filter: blur(4px);
border: 1px solid rgba(255,255,255,0.2);
.cta-btn:hover
background: #2b7e6b;
transform: scale(1.02);
box-shadow: 0 6px 14px rgba(0,0,0,0.3);
/* navigation dots & controls */
.nav-controls
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
padding: 1rem 0.5rem;
background: #0b0e14;
border-top: 1px solid #1f232c;
.dot-group
display: flex;
gap: 12px;
.dot
width: 10px;
height: 10px;
background: #4a4f5e;
border-radius: 20px;
transition: all 0.2s;
cursor: pointer;
.dot.active
background: #2ecc71;
width: 28px;
box-shadow: 0 0 6px #2ecc71;
.nav-btn
background: #1e212a;
border: none;
color: #cdd9ff;
font-size: 1.4rem;
padding: 6px 18px;
border-radius: 40px;
cursor: pointer;
transition: 0.15s;
font-weight: bold;
.nav-btn:hover
background: #2b7e6b;
color: white;
/* bottom info bar: like anthias asset info */
.info-bar
background: #080b10;
padding: 0.7rem 2rem;
display: flex;
justify-content: space-between;
font-size: 0.7rem;
color: #8f95a3;
border-top: 1px solid #191e26;
font-family: monospace;
/* responsive */
@media (max-width: 680px)
.anthias-bar
flex-direction: column;
align-items: flex-start;
.slide-title
font-size: 2rem;
.slide-description
font-size: 1rem;
.slide
padding: 1.5rem;
/* placeholder for dynamic background images (gradient fallback) */
.bg-gradient-1 background-image: linear-gradient(125deg, #0f2027, #203a43, #2c5364);
.bg-gradient-2 background-image: linear-gradient(125deg, #1e0b2c, #30133d, #511f5c);
.bg-gradient-3 background-image: linear-gradient(125deg, #1e2b2c, #2c4538, #3f6b51);
.bg-gradient-4 background-image: linear-gradient(125deg, #1f1c2c, #2a2a40, #3b2f52);
.bg-gradient-5 background-image: linear-gradient(125deg, #0f2b2d, #17433b, #1e6b5e);
/* animation for active slide subtle */
@keyframes fadeSlide
0% opacity: 0.6; transform: scale(0.98);
100% opacity: 1; transform: scale(1);
.slide
animation: fadeSlide 0.7s ease-out;
</style>
</head>
<body>
<div class="signage-container">
<!-- Screenly Anthias style header -->
<div class="anthias-bar">
<div class="brand">
<div class="logo-icon"><span>📺</span></div>
<h1>Screenly <span style="font-weight:300">|</span> Anthias</h1>
<div class="anthias">Portable Edition</div>
</div>
<div class="status-badge">
<div class="live-dot"></div>
<span>LIVE SIGNAGE</span>
<span>● 1080p Adaptive</span>
</div>
</div>
<!-- main content stage -->
<div class="content-stage">
<div class="carousel">
<div class="slides-wrapper" id="slidesWrapper">
<!-- Slide 1 - Brand Intro -->
<div class="slide bg-gradient-1">
<div class="slide-content">
<div class="slide-title">✨ Screenly Anthias</div>
<div class="slide-description">Professional open-source digital signage for Raspberry Pi & portable displays. Effortless content management, remote updates, and sleek presentations.</div>
<button class="cta-btn" data-info="Anthias Core">Explore Ecosystem →</button>
</div>
</div>
<!-- Slide 2 - Features -->
<div class="slide bg-gradient-2">
<div class="slide-content">
<div class="slide-title">⚡ Feature Rich</div>
<div class="slide-description">Schedule playlists • HTML overlays • Real-time asset sync • 4K support • REST API • Multi-screen orchestration.</div>
<button class="cta-btn" data-info="Features">Discover Integrations →</button>
</div>
</div>
<!-- Slide 3 - Portable Use -->
<div class="slide bg-gradient-3">
<div class="slide-content">
<div class="slide-title">📱 Portable & Resilient</div>
<div class="slide-description">Run on any screen, from Raspberry Pi Zero to high-res monitors. Offline caching, auto-recovery, and lightweight architecture.</div>
<button class="cta-btn" data-info="Portable">Deploy Anywhere →</button>
</div>
</div>
<!-- Slide 4 - Creative Showcase -->
<div class="slide bg-gradient-4">
<div class="slide-content">
<div class="slide-title">🎨 Dynamic Content</div>
<div class="slide-description">Images, videos, web pages, or real-time dashboards. Engage your audience with stunning visuals and responsive layouts.</div>
<button class="cta-btn" data-info="Creative">Launch Gallery →</button>
</div>
</div>
<!-- Slide 5 - Community / Anthias -->
<div class="slide bg-gradient-5">
<div class="slide-content">
<div class="slide-title">🌍 Open Source Power</div>
<div class="slide-description">Built on Anthias (formerly Screenly OSE). Join a vibrant community, contribute, and customize your signage experience.</div>
<button class="cta-btn" data-info="Community">Join Community →</button>
</div>
</div>
</div>
</div>
<!-- navigation -->
<div class="nav-controls">
<button class="nav-btn" id="prevBtn" aria-label="Previous slide">◀</button>
<div class="dot-group" id="dotContainer"></div>
<button class="nav-btn" id="nextBtn" aria-label="Next slide">▶</button>
</div>
<div class="info-bar">
<span>📡 Anthias Portable v2.5 • Digital Signage Engine</span>
<span id="slideCounter">Slide 1 / 5</span>
</div>
</div>
</div>
<script>
// ---------- Screenly Anthias Portable - Interactive Carousel + Auto-Rotate ----------
(function()
// DOM elements
const slidesWrapper = document.getElementById('slidesWrapper');
const slides = Array.from(document.querySelectorAll('.slide'));
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
const dotContainer = document.getElementById('dotContainer');
const slideCounterSpan = document.getElementById('slideCounter');
let currentIndex = 0;
const totalSlides = slides.length;
let autoRotateInterval = null;
const AUTO_INTERVAL_MS = 6000; // 6 seconds, typical signage rotation
let isTransitioning = false; // prevent rapid clicks during animation
// Helper: update carousel view (transform)
function updateCarousel(instant = false)
if (!slidesWrapper) return;
const offset = -currentIndex * 100;
if (instant)
slidesWrapper.style.transition = 'none';
slidesWrapper.style.transform = `translateX($offset%)`;
// force reflow then restore transition
slidesWrapper.offsetHeight;
slidesWrapper.style.transition = 'transform 0.6s cubic-bezier(0.2, 0.9, 0.4, 1.1)';
else
slidesWrapper.style.transform = `translateX($offset%)`;
// update dots active state
const dots = document.querySelectorAll('.dot');
dots.forEach((dot, idx) =>
if (idx === currentIndex)
dot.classList.add('active');
else
dot.classList.remove('active');
);
// update counter text
if (slideCounterSpan)
slideCounterSpan.innerText = `Slide $currentIndex+1 / $totalSlides`;
// go to specific slide index with safety checks
function goToSlide(index, fromAuto = false)
if (isTransitioning) return;
if (index < 0) index = totalSlides - 1;
if (index >= totalSlides) index = 0;
if (index === currentIndex && !fromAuto) return;
isTransitioning = true;
currentIndex = index;
updateCarousel(false);
// reset auto-rotate timer on manual interaction (but not if auto rotate triggers reset timer)
if (!fromAuto)
resetAutoRotate();
// after transition duration, unlock transitioning flag
setTimeout(() =>
isTransitioning = false;
, 650); // a bit more than transition (600ms)
// next slide
function nextSlide()
goToSlide(currentIndex + 1);
function prevSlide()
goToSlide(currentIndex - 1);
// reset auto-rotate: clear previous and start new
function resetAutoRotate()
if (autoRotateInterval)
clearInterval(autoRotateInterval);
autoRotateInterval = setInterval(() =>
// only auto advance if no active transition and user not hovering? we always allow but prevent race.
if (!isTransitioning)
nextSlide();
, AUTO_INTERVAL_MS);
// build dots from slides
function buildDots()
if (!dotContainer) return;
dotContainer.innerHTML = '';
for (let i = 0; i < totalSlides; i++)
const dot = document.createElement('div');
dot.classList.add('dot');
if (i === currentIndex) dot.classList.add('active');
dot.setAttribute('data-index', i);
dot.addEventListener('click', (e) =>
e.stopPropagation();
const idx = parseInt(dot.getAttribute('data-index'), 10);
if (!isNaN(idx) && idx !== currentIndex)
goToSlide(idx);
);
dotContainer.appendChild(dot);
// Add "click" handlers for CTA buttons inside slides: simulate Anthias action / alert with modern snackbar style
function attachButtonEvents()
const allButtons = document.querySelectorAll('.cta-btn');
allButtons.forEach(btn =>
// remove previous listeners to avoid duplicates
btn.removeEventListener('click', handleCtaClick);
btn.addEventListener('click', handleCtaClick);
);
function handleCtaClick(event) 'Anthias Feature';
// create a subtle temporary toast/notification (non-intrusive)
showToast(`🚀 Screenly Anthias • $info — portable signage ready.`);
// simple toast UI that disappears
function showToast(message)
// check existing toast
let toastEl = document.getElementById('anthias-toast');
if (toastEl)
toastEl.remove();
const toast = document.createElement('div');
toast.id = 'anthias-toast';
toast.innerText = message;
toast.style.position = 'fixed';
toast.style.bottom = '30px';
toast.style.left = '50%';
toast.style.transform = 'translateX(-50%)';
toast.style.backgroundColor = '#1e2a2f';
toast.style.backdropFilter = 'blur(12px)';
toast.style.color = '#e0f2fe';
toast.style.padding = '12px 28px';
toast.style.borderRadius = '60px';
toast.style.fontSize = '0.9rem';
toast.style.fontWeight = '500';
toast.style.fontFamily = 'system-ui, monospace';
toast.style.border = '1px solid #2b7e6b';
toast.style.boxShadow = '0 12px 20px rgba(0,0,0,0.3)';
toast.style.zIndex = '9999';
toast.style.letterSpacing = '0.3px';
toast.style.pointerEvents = 'none';
document.body.appendChild(toast);
setTimeout(() =>
if (toast && toast.parentNode) toast.remove();
, 2800);
// keyboard navigation for accessibility & pro feeling (left/right arrows)
function handleKeydown(e)
if (e.key === 'ArrowLeft')
e.preventDefault();
prevSlide();
resetAutoRotate();
else if (e.key === 'ArrowRight')
e.preventDefault();
nextSlide();
resetAutoRotate();
// Pause auto-rotate on hover (professional signage often pauses when interaction)
let hoverTimer = null;
function pauseAutoRotateTemporarily()
if (autoRotateInterval)
clearInterval(autoRotateInterval);
autoRotateInterval = null;
function resumeAutoRotate()
if (!autoRotateInterval)
autoRotateInterval = setInterval(() =>
if (!isTransitioning)
nextSlide();
, AUTO_INTERVAL_MS);
// attach hover events on the whole container to pause (like user attention)
const container = document.querySelector('.signage-container');
if (container)
container.addEventListener('mouseenter', () =>
pauseAutoRotateTemporarily();
);
container.addEventListener('mouseleave', () =>
if (!autoRotateInterval)
resumeAutoRotate();
);
// for touch devices: pause on touchstart but resume after some time? we do basic resume on touchend.
container.addEventListener('touchstart', () =>
pauseAutoRotateTemporarily();
);
container.addEventListener('touchend', () =>
// resume after short delay
setTimeout(() =>
if (!autoRotateInterval) resumeAutoRotate();
, 4000);
);
// Initialization: build UI, start rotation, and fix initial positioning
function init()
buildDots();
// ensure first slide active
currentIndex = 0;
updateCarousel(true); // instant set without animation
setTimeout(() =>
// reattach transition properly
if (slidesWrapper)
slidesWrapper.style.transition = 'transform 0.6s cubic-bezier(0.2, 0.9, 0.4, 1.1)';
, 20);
attachButtonEvents();
// Event listeners for nav
if (prevBtn) prevBtn.addEventListener('click', () => prevSlide(); resetAutoRotate(); );
if (nextBtn) nextBtn.addEventListener('click', () => nextSlide(); resetAutoRotate(); );
window.addEventListener('keydown', handleKeydown);
// start auto rotation
resetAutoRotate();
// add dynamic info: show that Anthias portable supports realtime
console.log('Screenly Anthias Portable — Digital signage active');
// simulate online status info
const infoBarSpan = document.querySelector('.info-bar span:first-child');
if (infoBarSpan)
// extra flair: update time occasionally
setInterval(() =>
const now = new Date();
const timeStr = now.toLocaleTimeString([], hour:'2-digit', minute:'2-digit', second:'2-digit');
if (infoBarSpan && !infoBarSpan.innerHTML.includes('⏱️'))
// optionally but keep original clean
const baseText = "📡 Anthias Portable v2.5 • Digital Signage Engine";
const timeDisplay = ` ⏱️ $timeStr`;
if(!infoBarSpan.innerHTML.includes('⏱️'))
infoBarSpan.innerHTML = baseText + timeDisplay;
else
// update time part only
infoBarSpan.innerHTML = baseText + ` ⏱️ $timeStr`;
else if(infoBarSpan)
const baseClean = "📡 Anthias Portable v2.5 • Digital Signage Engine";
infoBarSpan.innerHTML = baseClean + ` ⏱️ $timeStr`;
, 1000);
// Optional: detect any dynamic content, but we also can watch for window resize to keep full width
window.addEventListener('resize', () =>
// re-align transform if needed (just reapply same offset)
if (slidesWrapper && !isTransitioning)
const offset = -currentIndex * 100;
slidesWrapper.style.transform = `translateX($offset%)`;
);
// start everything when DOM fully loaded
if (document.readyState === 'loading')
document.addEventListener('DOMContentLoaded', init);
else
init();
// Additional fallback for dynamic button rebinding if slides change (but static slides, fine)
// For future proof: use MutationObserver for new buttons? not needed.
// However, ensure that dynamic CTA buttons inside slides keep working if re-rendered? But we are static.
// Re-attach after possible slide update? not needed.
// add a small interval to guarantee button listeners? No, all static.
setInterval(() =>
// double-check buttons for any dynamic replacement (safety)
attachButtonEvents();
, 5000);
)();
</script>
</body>
</html>
Anthias, formerly known as Screenly OSE, is the world's most popular open-source digital signage software. Managed by Screenly, Inc., it allows users to turn any HDMI-ready display into a digital sign using a Raspberry Pi or x86 hardware.
While it is not a "portable" device you buy off a shelf, its small footprint on hardware like the Raspberry Pi makes it a highly portable signage solution for temporary events, mobile kiosks, or local business displays. Anthias: The Open-Source Powerhouse | Metric | Unit A | Unit B
Anthias is designed for single-screen deployments where simplicity and local control are the priority. It is completely free and "cloud-free," meaning it lives and runs entirely on your local network. Key Features
Media Support: Plays 1080p HD video, high-resolution images (JPG, PNG, GIF), and live web pages.
Local Management: Accessible via a browser on your local network using the device's IP address.
Scheduling: Create playlists and schedule content to change automatically throughout the day (e.g., breakfast vs. dinner menus).
Hardware Versatility: Optimized for Raspberry Pi (including Pi 4 and Pi 5) and standard x86 PCs.
Anthias - The world's most popular open source ... - Screenly
Anthias (formerly Screenly OSE) is the world's most popular free and open-source digital signage software for Raspberry Pi and PCs. It is designed for individual users or small businesses that want a cost-effective, standalone way to display content on a single screen. Key Features
Cost-Free Management: Entirely open-source with no recurring subscription fees.
Media Support: Displays images, web pages, and video content in 1080p Full HD resolution.
Intuitive Web Interface: Allows you to upload assets and manage playlists from any computer on the same local network. Why go through this trouble instead of buying
Scheduling: Enables you to set specific start/end times and durations for your assets, perfect for changing menus throughout the day. Hardware Requirements
To set up a "portable" or standalone Anthias station, you generally need: What are the hardware requirements? - Screenly Support
1. The Compute Unit: Raspberry Pi 4 or 5
2. The Power Source: USB-C Power Bank (PD Standard)
3. The Display: Portable USB-C Monitor
4. The Network: Onboard Wi-Fi Hotspot
http://screenly.local (or the Pi's static IP: 192.168.50.1), and upload new assets instantly.5. The Case: Rugged or Rackmount
SSH into your Pi. Run the following commands to set up an Access Point that starts automatically on boot.
sudo apt install hostapd dnsmasq
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
Configure /etc/dhcpcd.conf to give the Pi a static IP (192.168.4.1). Then configure hostapd.conf for your SSID. Once rebooted, your Screenly Anthias player will broadcast its own Wi-Fi.
Pro Tip: Install watchdog so that if the Wi-Fi dongle or Pi crashes in the field, it auto-reboots.