5
16 Comments

I kept re-importing my playlists on every device, so I built a media player that syncs

Hey IH — I'm Shamir, maker of Tuneline (https://tuneline.app), a cross-platform media player with cloud sync.

The itch: I used a different media player on desktop, phone, and the big screen, and none of them shared anything. Same playlists imported three times. Favorites and settings never matched. So I built the thing I wanted — bring your own playlists, and your library + favorites + settings sync across every device, managed from a web dashboard.

Where it's at:

  • Native apps live on macOS, Windows, Linux (Snap + Flathub), Android, Google TV, and iOS
  • Full program guide, on-demand + series browsing, cinematic dark UI
  • Free forever on one device (no viewing feature is paywalled); a one-time purchase unlocks cloud sync + multi-device. No subscriptions.

Business model: reverse-trial freemium. Every playback feature stays free; the paid tier is purely sync/backup/multi-device — I deliberately never gate the viewing experience, because taking features away from free users burns goodwill.

Stack: Flutter (single codebase across 6 platforms), Node/Prisma API, self-hosted.

What I'd love feedback on:

  1. Is "sync across devices" a strong enough wedge to pay once for, when the player itself is free?
  2. For a freemium where the free tier is genuinely complete, how do you nudge conversion without nagging?

Happy to answer anything about the build or the cross-platform Flutter experience.

posted to Icon for group Building in Public
Building in Public
on June 12, 2026
  1. 1

    Update + a sharper follow-up, now that I have real data on the "free tier is too complete" worry some of you raised.

    Last 24h of active devices:

    • 64% (7 of 11) never sign in at all — open the app, load a playlist, watch, leave. No account, ever.
    • That anonymous group generated 965 telemetry events vs 49 for signed-in users. So my MOST engaged users are the ones giving me zero handle to convert.
    • Signed-in side: 4 devices map to only 3 accounts (the one person syncing across two devices is exactly my paying persona).

    So the free tier is doing its job almost too well: people get full value without ever creating an account, and I have no email, no relationship, nothing to nudge — a silent, engaged, account-free majority.

    For folks who've run a "free tier is genuinely complete" model: how do you convert the account-free majority WITHOUT gating playback? Three angles I'm torn on:

    1. Introduce one gentle, account-worth friction point (e.g. "pick up where you left off" / "save this layout") — useful enough to sign up for, but on something additive, not something I took away.
    2. Only ask at the 2nd-device moment — leave the single-device user completely alone, and only surface sync when they actually install on a phone AND a TV.
    3. Or is an engaged account-free user just permanently lost revenue you should stop optimizing for?

    Trying hard to avoid the nag-everyone trap. What's actually moved the needle for you?

  2. 2

    this is solid, the idea of free player + paid sync is way better than paywalling features

    1. 1

      Thanks! that's the exact line I didn't want to cross. Gating playback would've meant punishing the people who liked the app most. Sync is purely additive, so paying for it never takes anything away from anyone.

  3. 2

    Sync is a real wedge, but only for the multi-device user, and that is not most of your installs. The single-device person will never pay no matter how good sync is, so do not spend conversion effort there. The leverage is timing: the moment someone signs into a second device and sees an empty library is when the pain is live and the wallet opens. Sell sync there, not on the landing page. On nudging without nagging, lean on loss aversion over convenience. "You have 18 playlists and 300 favorites on this device, back them up so you never have to rebuild them" converts better than "sync across your devices," because people pay to protect what they built more than to gain a nicety. One business flag worth thinking about now: a one-time price against a self-hosted, ongoing sync cost is a margin trap as your paid base grows. Every paying user costs you server money forever but paid you once. Watch that curve before it bites, you may want a small recurring tier for heavy sync users down the road.

    1. 1

      The second-device timing point is well taken, I've heard it enough times in this thread now that I'm convinced the landing page is the wrong place to pitch sync at all. The margin trap is the one that actually nags at me though. Right now the payloads are tiny so per-user cost is low, but you're right that one-time-revenue against forever-cost compounds the moment the paid base grows. I've been resisting a subscription because "no subscriptions" is part of why people trust the app, but a small recurring tier for genuinely heavy multi-device users might be the honest version of that. Watching the curve before I commit either way. Appreciate you flagging it this early.

  4. 2

    The 'scratch your own itch' origin is the strongest signal a product can have — you already know the pain is real because you lived it.

    One thing worth thinking about early: the moment a second device enters the picture is when sync earns its price. That gap — opening your app on a new device and finding nothing there — is the exact moment to surface the upgrade prompt, not on day one when everything still feels fine. Timing the ask to the pain beats any copy you could write.

  5. 2

    The playlist re-importing grind is so real. How are you handling different file formats or quality levels across devices?

    1. 1

      Good question. I don't sync the media itself, only your library: playlist sources, favorites, settings, watch position. Each device pulls its own streams and picks quality locally, so a phone on cellular and a TV on wifi each do their own thing independently. Keeps the sync payload tiny (it's text, not bytes) and sidesteps any re-encoding/format mismatch. The thing that travels between devices is "what you set up," not the video.

  6. 2

    On my own app I went the opposite way from your Flutter call — stayed native and single-platform — and the tradeoff showed up exactly at sync: one device meant I never had to reconcile state, which is the boring tax cross-platform makes you pay early. So I think your wedge is real, but it only bites the instant someone opens device two. On nudging without nagging: don’t prompt on a timer, prompt on the event — the first time they sign in elsewhere and their library isn’t there, that gap sells sync better than any banner could. Have you tried surfacing the upgrade only at that second-device moment, or is it always visible?

    1. 1

      Honest answer: not precisely yet, and you're right that the number probably caps conversion harder than any copy does. I can see device registrations per account server-side, but I haven't cut a clean "% of active free users with 2+ devices" figure. \That's now top of my list, because it tells me whether the wedge is even addressable before I touch the pitch. Thanks for pointing at the thing I should measure instead of guessing.

  7. 2

    Sync as a paid wedge can work, but timing is everything. The upsell falls flat
    on day one because the user is still single-device and feels zero pain. It only
    lands the first time they pick up their phone expecting their playlist and
    position from the TV to be there. I would let them hit that gap naturally (open
    on a second device, see nothing synced) instead of pitching it upfront.

    That also answers your nagging question: tie the prompt to a moment of real need,
    not a timer. Someone who just added a third device, or restored after a reinstall,
    is the person who actually wants sync. One prompt there beats five generic ones.
    I am chewing on the same thing for a free app of mine where the free tier is meant
    to stay complete.

    Honest question though: do you know how many of your free users are even
    multi-device? That number probably caps conversion more than the copy does.

  8. 2

    You asked how to nudge freemium conversion without nagging. Here's where your page is already doing it — just with the wrong signal.

    "Play Anywhere. Sync Everywhere." — both read as the same offer. But Play Anywhere is free; Sync Everywhere costs $34.99. A visitor who reads that headline, downloads the free app, and hits a paywall at sync didn't get a nudge — they got a surprise.

    The fix is naming the line at the exact moment they're deciding whether to download:

    Before: "Play Anywhere. Sync Everywhere."
    After: "Play Anywhere — free. Sync Everywhere with Pro — $34.99 once."

    A visitor who reads that and still wants sync is already pre-sold on the upgrade. No popup, no modal, no nag.

    Second: your "$34.99 One-Time Purchase" stat in the bar is plain text — a visitor ready to pay can't click it above the fold.

    Before: "$34.99 One-Time Purchase" (non-clickable text)
    After: "$34.99 · One-time · 7-day free trial →" (link to /pricing)

    Two string edits, no design work. Your other 2 above-fold gaps are in the Fix Sprint if you want them done together: https://outboundautonomy.com/fix-sprint

    https://outboundautonomy.com/images/tuneline-finding-card-20260612.png

    1. 1

      Follow-up: tried the "free vs paid split in the headline" fix on another media product's landing page this week. The founder said conversion on the upgrade click moved noticeably just from naming the line.

      Your version of this change is "Play Anywhere — free. Sync Everywhere with Pro — $34.99 once." — same principle.

      If you want the remaining two gaps done with the same specificity (the clickable pricing stat + one more above-fold issue), that's the Fix Sprint: https://outboundautonomy.com/fix-sprint?ref=fixsprint-tuneline

      $49, in your inbox in 48h. Checkout is a secure one-time Stripe payment, branded Outbound Autonomy.

  9. 2

    I'd be careful with one thing.

    The interesting question may not be whether sync is strong enough to pay for.

    It may be what decision users believe they're making when they pay for it.

    Those can sound similar while leading to very different signals about demand.

    I wouldn't make that call casually this early.

    1. 1

      That's the sharper framing — thanks. You're right they're different questions with different demand signals. My current read: people aren't paying for "sync" the feature, they're paying to never set their library up twice — the value is "it's just already there on the next device." I'm trying to validate that's the real job before I harden anything. What signal would you watch to tell those two apart?

      1. 2

        Possibly, but that's exactly why I stopped short earlier.

        I don't think the interesting part is the signal itself.

        I think it's the decision sitting underneath what that signal is being used to validate.

        I'd be careful answering that casually in a thread.

        If you'd like the tighter version, drop your email and I'll put it together properly.

Trending on Indie Hackers
6 weeks solo, 2 rejections, finally live but nobody told me marketing would be this hard User Avatar 131 comments Building ExpenseSpy solo, no funding — launching June 17 on iOS & Android User Avatar 54 comments I just wanted to taste AI coding tools. A week passed. User Avatar 17 comments I spent more time setting up cold email than actually selling. Here is what fixed it. User Avatar 15 comments Building LinkCover – Day 3: Payment is live. No more building, time to sell. User Avatar 15 comments I Was Bypassing Every App Blocker, So I Built One That Fights Back User Avatar 11 comments