Freebee Ads docs

Engineering docs

Player setup runbook: make a screen open /player on boot

Last updated Oct 20, 2018 · 8 sections

This is for ops. It covers the three boxes we put behind mall screens today (a Windows mini PC, a Mac mini, an Android TV box) and tells you how to make each one open the browser player full screen every time it powers on, stay awake, and recover on its own. Read it once end to end before your first install. The iPad quick start lives in web/PLAYER.md.

The player URL is https://<your web host>/player. Add ?vision=1 to turn the camera counter on at first load (it asks for permission once; only counts leave the device, never images). It counts people walking past and the faces that look; use ?vision=faces on a box too slow for that. Check the camera with /player/vision-test before going live (docs/AUDIENCE_MEASUREMENT.md).

What a good install looks like

  1. Box powers on, logs in by itself, Chrome opens full screen on /player.
  2. First time: the screen shows a 6-character code. Type it into Devices > Pair a device and pick the screen. The code refreshes itself if it expires, so there is no rush.
  3. Within a minute the loop starts. On the Devices page the card for that screen shows: a green last check-in dot, the player version (web-1.1.0 or later), uptime climbing, cache "n of n ready", queued records 0, camera "counting" (if you enabled it), and "Healthy".
  4. Pull the wifi for a few minutes. The screen keeps looping from its cache, the card's dot goes amber then red, and "queued records" grows on the player's own status overlay (tap any corner 5 times, or add ?debug=1). Plug wifi back in: the records upload in order and the dot goes green. Nothing is counted twice.

If step 3 never happens, the checklist at the end of this page is for you.

Windows mini PC (Windows 10 or 11, Chrome)

  1. Create a local account for the screen with no password: Settings > Accounts > Other users > Add account > "I don't have this person's sign-in information" > "Add a user without a Microsoft account". Name it screen.

  2. Auto sign-in: press Win+R, run netplwiz, untick "Users must enter a user name and password", pick screen, OK. (On Windows 11 if the box is missing, set the registry value HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device\DevicePasswordLessBuildVersion to 0 and reopen netplwiz.)

  3. Never sleep: Settings > System > Power > Screen and sleep: all "Never". Then in Control Panel > Power Options > Change plan settings > Change advanced power settings: Hard disk "Never", USB selective suspend "Disabled". In BIOS, turn on "Restore on AC power loss" (or "Power on after power failure") so the box boots itself after an outage.

  4. Disable Windows Update reboots as far as the edition allows: Settings

    Windows Update > Advanced options > Active hours 00:00 to 23:00 is not possible, so set 10:00 to 23:00 (the mall day) and accept that overnight reboots happen. The player comes back on its own after a reboot.

  5. Kiosk shortcut: create a file C:\Users\screen\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\player.cmd with this content (one line for the Chrome command):

    @echo off
    timeout /t 20 /nobreak >nul
    start "" "C:\Program Files\Google\Chrome\Application\chrome.exe" --kiosk --noerrdialogs --disable-infobars --disable-session-crashed-bubble --autoplay-policy=no-user-gesture-required --check-for-update-interval=31536000 --user-data-dir=C:\screen-profile "https://<your web host>/player?vision=1"
    

    The 20 second wait lets wifi connect first. --user-data-dir keeps the screen's pairing separate from any other Chrome profile on the box.

  6. Hide the mouse pointer: install AutoHideMouseCursor (free) in the same Startup folder, or just unplug the mouse after setup.

  7. Reboot and watch it come up by itself. Pair it. Done.

Exit kiosk mode on site: Alt+F4 closes Chrome; the player restarts at the next reboot. To open the player's status overlay instead, tap or click a screen corner 5 times.

Mac mini (macOS 13 or later, Chrome)

  1. Account: System Settings > Users & Groups > add a Standard user screen with a simple password (macOS requires one). Then under Login Options set "Automatically log in as" screen. FileVault must be OFF for auto login to work (System Settings > Privacy & Security > FileVault).

  2. Never sleep: System Settings > Displays > Advanced: "Prevent automatic sleeping when the display is off" on. Then in Terminal, as an admin:

    sudo pmset -a sleep 0 displaysleep 0 disksleep 0 autorestart 1 womp 1
    sudo systemsetup -setrestartfreeze on
    

    autorestart 1 boots the Mac after a power cut. Also turn off the screen saver and "Require password after sleep" for the screen user.

  3. Kiosk launcher: as the screen user, create ~/Library/LaunchAgents/com.freebee.player.plist:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0"><dict>
      <key>Label</key><string>com.freebee.player</string>
      <key>ProgramArguments</key><array>
        <string>/Applications/Google Chrome.app/Contents/MacOS/Google Chrome</string>
        <string>--kiosk</string>
        <string>--noerrdialogs</string>
        <string>--disable-infobars</string>
        <string>--disable-session-crashed-bubble</string>
        <string>--autoplay-policy=no-user-gesture-required</string>
        <string>--user-data-dir=/Users/screen/screen-profile</string>
        <string>https://<your web host>/player?vision=1</string>
      </array>
      <key>RunAtLoad</key><true/>
      <key>KeepAlive</key><true/>
      <key>ThrottleInterval</key><integer>10</integer>
    </dict></plist>
    

    Load it once with launchctl load ~/Library/LaunchAgents/com.freebee.player.plist. KeepAlive relaunches Chrome if it ever quits or crashes.

  4. Camera permission (only if you use ?vision=1): the first launch asks "Chrome would like to access the camera". Click OK once; macOS remembers.

  5. Hide the pointer: unplug the mouse, or move it to a corner. Chrome kiosk hides it after a few seconds of no movement.

  6. Reboot and confirm it comes up by itself. Pair it.

Exit kiosk mode on site: Cmd+Q quits Chrome; KeepAlive relaunches it in 10 seconds, so first run launchctl unload ~/Library/LaunchAgents/com.freebee.player.plist from Terminal (switch user with fast user switching or SSH in).

Android TV box (Android TV 11 or later, or any Android box)

Android TV's Chrome is not in the Play Store on most boxes. Use one of:

  • Fully Kiosk Browser (paid, recommended): it is built for this. Install it from the Play Store (or sideload the APK), then in its settings set Start URL https://<your web host>/player?vision=1, turn on "Launch on boot", "Keep screen on", "Kiosk mode", "Autoplay videos", "Enable camera access" (if you use vision), and "Reload on internet reconnect" OFF (the player handles reconnect itself and reloading would restart the loop).
  • Chrome sideloaded with the ADB commands below.

ADB route (box in developer mode, adb connect <box ip>):

adb install chrome.apk
# keep the box awake while plugged in
adb shell settings put global stay_on_while_plugged_in 7
adb shell settings put system screen_off_timeout 2147483647
# open the player now
adb shell am start -n com.android.chrome/com.google.android.apps.chrome.Main -d "https://<your web host>/player?vision=1"

To launch at boot, install a small launcher app such as "AutoStart - No root" and point it at Chrome, or set Fully Kiosk as the Home app (Settings > Apps > Default apps > Home app). Then open the overlay on the screen once (tap a corner 5 times with a USB mouse) and press Fullscreen; Chrome remembers it for that site.

Android boxes are the least reliable of the three: Chrome on Android drops large video caches under memory pressure, there is no true kiosk mode without Fully Kiosk, and some boxes ignore the wake settings. Prefer a mini PC for a screen that sells premium slots.

Wake lock and auto update

  • The player asks the browser for a wake lock so the display stays on even if the box's settings slip. The overlay shows "Wake lock: active". Browsers only grant it to a visible tab in a secure (https) context.
  • The player checks for a new build every 5 minutes and reloads itself at the next slot boundary. You never need to visit a screen for an update.
  • Every 15 seconds the player checks in with its health (version, uptime, cache, queued records, camera state, last error). This is what the Devices page shows.

Remote fixes from the Devices page

Before you drive to the mall, try these from the card:

  • Reload when the page looks frozen or shows an old build.
  • Restart the loop when ads stopped advancing but the page responds (for example after a long outage). Nothing is downloaded again.
  • Clear cache when a creative looks wrong or outdated. The player drops its stored files and fetches today's loop again. Play records are not touched.

The screen runs a command at its next check-in (within 15 seconds when it is online) and reports a one-line result back onto the card.

When it does not pair or check in

  1. The screen shows "API unreachable, retrying pairing": the box has no internet, or the web host cannot reach the backend. Check wifi first.
  2. The code was accepted but Pair a device keeps waiting: the screen may have reloaded and now shows the same code (fine, keep waiting) or a new one (type the new one).
  3. The card shows an old last check-in but the screen is playing: it is offline and playing from cache. That is the design. Fix the network; the queued records upload themselves.
  4. Camera says "no permission": the browser blocked the camera. On the box, open the overlay, press "Vision off" then on again to re-prompt, or allow the camera in the browser's site settings for the player host.

Limits of the browser player (what the native app will remove)

  • A browser cannot start itself; it depends on the OS auto login and kiosk tricks above, which a Windows update or a macOS prompt can undo.
  • Storage is at the browser's mercy. Chrome may evict cached creatives when the disk is low; the player then re-downloads at the next online moment.
  • No hardware watchdog: if Chrome hangs hard, only a power cycle (or the Reload command, if the tab still checks in) brings it back.
  • Camera counting runs in JavaScript and costs CPU on cheap boxes; counts may be lower than a native sensor would report.
  • Screenshots of what is actually on the glass are not possible from a browser; the native app will add a periodic on-device thumbnail that stays on the device unless ops asks for it.
Player setup · Docs