RORK LABEN
MAX — Rork MaxはReact NativeではなくネイティブSwiftアプリを生成し、Appleエコシステム全体を対象にしますDEVICES — iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageまで、一つの記述から広げられますNATIVE — AR・LiDARスキャン、Metalによる3Dゲーム、ウィジェット、Dynamic Island、オンデバイスCore MLを解放しますSEED — RorkはLeft Lane Capital主導の$15Mシードを調達し、Peak XVやa16z Speedrunも参加しましたPAPERLINE — アプリビルダーPaperlineを買収し、エンジニアリング人材の獲得を続ける姿勢ですMARKET — 月間743,000訪問超。Gartnerは2026年末までに新規アプリの75%がローコード/ノーコードで作られると見込みますMAX — Rork MaxはReact NativeではなくネイティブSwiftアプリを生成し、Appleエコシステム全体を対象にしますDEVICES — iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageまで、一つの記述から広げられますNATIVE — AR・LiDARスキャン、Metalによる3Dゲーム、ウィジェット、Dynamic Island、オンデバイスCore MLを解放しますSEED — RorkはLeft Lane Capital主導の$15Mシードを調達し、Peak XVやa16z Speedrunも参加しましたPAPERLINE — アプリビルダーPaperlineを買収し、エンジニアリング人材の獲得を続ける姿勢ですMARKET — 月間743,000訪問超。Gartnerは2026年末までに新規アプリの75%がローコード/ノーコードで作られると見込みます
記事一覧/開発ツール
開発ツール/2026-07-15上級

Rorkの癒しアプリにスリープタイマーを付けたら、フェードアウトが実際の音とズレた話

Rorkが生成するスリープタイマーは、壁時計のsetIntervalで音量を下げます。数値上は30分でも、実際の音はもっと早く消えたり不自然に途切れたりします。フェードを再生位置で駆動し直す実装と、対数カーブ・停止処理・画面ロック時の限界までを実運用の視点でまとめました。

Rork507expo-av5スリープタイマーReact Native207音声処理癒しアプリ2

プレミアム記事

個人開発で Relaxing Healing という癒し系アプリを長く運営していると、「音が消える瞬間」の設計がアプリの印象を大きく左右することを何度も実感してきました。眠りに落ちる直前、音がプツッと切れれば人は目を覚まします。だからこそスリープタイマーのフェードアウトは、地味ですが最後の一手として重要な機能です。

先日、新しい癒しアプリの試作をRorkで進めていたとき、このスリープタイマーで数時間つまずきました。シミュレータでは30分後にきれいに音が消えていくのに、実機で試すと「思ったより早く音が小さくなる」「最後の数秒だけ急に途切れる」という違和感が残ります。原因を追ってみると、Rorkが生成したコードには音声フェード特有の落とし穴がいくつも重なっていました。同じジャンルのアプリを作る方が必ずぶつかる部分なので、直し方を整理しておきます。

Rorkが生成するスリープタイマーの典型形

「30分後に音量をゆっくり下げて停止するスリープタイマーを付けて」とRorkに依頼すると、多くの場合こういうコードが返ってきます。

// Rorkが生成しやすいパターン
const FADE_MS = 30_000; // 最後の30秒でフェード
const TICK_MS = 200;
 
function startSleepTimer(sound, totalMinutes) {
  const stopAt = Date.now() + totalMinutes * 60_000;
 
  const id = setInterval(async () => {
    const remaining = stopAt - Date.now();
    if (remaining <= 0) {
      await sound.stopAsync();
      clearInterval(id);
      return;
    }
    if (remaining <= FADE_MS) {
      const volume = remaining / FADE_MS; // 1.0 → 0.0
      await sound.setVolumeAsync(volume);
    }
  }, TICK_MS);
 
  return id;
}

一見すると正しく見えます。Date.now() で残り時間を測り、フェード区間に入ったら線形に音量を下げる。動かすと確かに音は小さくなっていきます。けれど、このコードは3つの層で実際の音とズレます。

壁時計で測ると、なぜ実際の音とズレるのか

第一の問題は、setInterval が壁時計(wall clock)を基準にしていることです。setInterval(fn, 200) はぴったり200msごとには呼ばれません。JSスレッドが画像のデコードやリスト描画で忙しければ、200msの間隔は250msにも400msにも伸びます。フェードのように「なめらかさ」が命の処理では、この揺らぎがそのまま音量のガタつきになります。

第二に、sound.setVolumeAsync() は非同期です。200msごとに await を挟むと、ネイティブ側への反映が詰まったときにコールバックが積み上がり、音量の更新が飛び飛びになります。

そして第三に、最も見落とされやすいのが「音声の再生位置」と「壁時計」が同じ速度で進むとは限らないことです。オーディオセッションが割り込み(電話・他アプリの音)から復帰したとき、あるいはループの継ぎ目で僅かに再バッファが起きたとき、実際に鳴っている音の位置は壁時計から遅れます。壁時計だけを見ていると、音はまだ鳴っているのにタイマーが先に「終わり」と判断し、フェードの途中で急に切れてしまうのです。

観点壁時計 setInterval再生位置ドリブン
基準にする時間Date.now()実際の再生位置 positionMillis
JSが重いとき間隔が伸びて音量がガタつく次の更新で正しい音量に追従
割り込み復帰後音と時間がズレて途中で切れる音の位置に同期し続ける
フェードの決定性累積誤差で毎回ぶれる位置から一意に決まる

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
Rorkが吐くsetIntervalフェードがなぜ実際の音とズレるかを理解し、再生位置で駆動する正しい実装に置き換えられる
線形に音量を下げると不自然に速く消えて聞こえる理由と、対数カーブで自然なフェードにする具体的な計算を手に入れられる
画面ロック中はJSのフェードが止まるという限界を正しく知り、事前フェード済みのテール音源で確実に消す現実解を選べる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

開発ツール2026-05-13
Rork で癒し系アプリのアンビエントサウンドを実装して詰まった3つのこと
癒し・瞑想系アプリのアンビエントサウンド実装でRorkが苦手な3つのパターンを解説。ループ途切れ・iOSサイレントモード・バッテリー消耗の問題をexpo-avで解決する実践コード付き。
開発ツール2026-05-05
Rork でポッドキャストアプリを作る実装ガイド:バックグラウンド再生・RSS 取得・オフラインダウンロードを本番レベルで動かす
Rork でポッドキャストアプリを本番レベルで構築する完全実装ガイド。expo-av によるバックグラウンド再生・RSS フィード解析・オフラインダウンロード・ロック画面対応まで、動作するコードで丁寧に解説します。
開発ツール2026-03-28
Rork で音楽プレイヤーアプリを作る — expo-av によるオーディオ再生の実装ガイド
Rork と expo-av を使って音楽プレイヤーアプリを構築する方法を解説。再生・一時停止・シークバー・プレイリスト管理まで、実践的なコード例とともにステップバイステップで紹介します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →