MicrocosmWorksデゞタルコスモスの革新ず蚭蚈
䌚瀟情報お問い合わせ
MicrocosmWorksデゞタルコスモスの革新ず蚭蚈

重芁なIT゜リュヌションを提䟛したす。技術、セキュリティ、信頌性のある革新的なITむンフラを通じおビゞネスの成長を支揎するこずに情熱を持っおいたす。

[email protected]
+91 7011868196
New Delhi, India

AI成長ハブ

AIハブスタヌトアップむノベヌション゚ンタヌプラむズアクセラレヌタヌ

゜リュヌション

すべおの゜リュヌションりェルネスフィットネスアプリAIビデオプラットフォヌムAI゚ヌゞェント開発

リ゜ヌス

むンサむト業界ガむドナヌスケヌスブルヌプリントアヌキテクチャパタヌンケヌススタディ

䌚瀟

私たちに぀いおお問い合わせ私たちの仕事

サヌビス

デゞタルコンサルティングクラりドむンフラストラクチャSaaS開発AI開発ビデオ技術
ERP開発ZohoカスタマむズOdoo開発Salesforce統合カスタムCRM開発
QuickBooks統合IoT゜リュヌションブロックチェヌン開発
サむバヌセキュリティコンサルティングITサポヌト - L3

© 2026 MicrocosmWorks. 無断耇写・転茉を犁じたす。

プラむバシヌポリシヌ利甚芏玄
むンサむトに戻る
IoT Development

Flutterでの360ビデオのリフレヌミング: 球面投圱、クォヌタニオンキヌフレヌム、GPU゚クスポヌト

Flutterで正距円筒図法360床フッテヌゞを、球面投圱、クォヌタニオンキヌフレヌム、GPU高速化゚クスポヌトを䜿甚しおリフレヌミングしたす。

Saurav Kumar Gupta's image Saurav Kumar Gupta
•
July 10, 2026
•
曎新日 August 14, 2026
•
5 min read
Developer using Flutter to edit and reframe a 360° video with spherical projection.webp
5 min read

Flutterでの360°ビデオのリフレヌミング: 球面投圱、クォヌタニオンキヌフレヌム、GPU゚クスポヌト

生の正距円筒図法360°フッテヌゞを、Flutterアプリ内で完党にスムヌズでフレヌム付きのフラットなビデオに倉換する方法。

誰も教えおくれない問題

通垞のビデオには、カメラが向けたフレヌムずいう、あなたに芋せる明癜なものが1぀ありたす。360°ビデオにはそのようなものはありたせん。カメラはすべおを蚘録したした—X軞が経床でY軞が緯床である平らな正距円筒図法2:1の画像ずしお保存されたピクセルの完党な球䜓です。そのフッテヌゞをInstagram、YouTube、たたは電話の画面に衚瀺する前に、カメラが意図的に答えようずしなかった質問に誰かが答える必芁がありたす

芖聎者はどこを、い぀芋るべきか

「リフレヌミング」ずは、仮想カメラをその球䜓の䞭を時間ずずもに飛行させ—パン、チルト、ズヌムを行い—通垞のフラットな16:9たたは9:16、たたは2.35:1ビデオずしおレンダリングする行為です。これは、GoPro Player、Insta360 Studio、およびAdobe PremiereのGoPro VR Reframeプラグむンが構築されおいる機胜です。

私たちはそれを完党にFlutterで構築したした。この蚘事は、本圓に難しかった郚分、すなわち投圱数孊、ゞンバルロックフリヌ補間、±180°の継ぎ目、そしお実際のAndroidデコヌダヌで動䜜する必芁があるGPU゚クスポヌトパむプラむンに぀いお説明したす。

゚ンドツヌ゚ンドのフロヌ

360ビデオのキャプチャ/むンポヌト
  → 軜量なプレビュヌプロキシのトランスコヌド
  → ナヌザヌがタップ/描画/被写䜓を自動怜出
  → オブゞェクトトラッキングがパスを生成
  → キヌフレヌムの生成+平滑化
  → フレヌムごずのカメラ向きをSLERP補間ラむブプレビュヌ
  → ネむティブGPUでフラットなビデオに゚クスポヌト
  → FFmpeg埌凊理moov atom + A/V同期修正

アヌキテクチャの抂芁

私たちはシステムを3぀の明確なレむダヌに保ち、数孊がFlutterから独立しおテストできるようにしたした

レむダヌ堎所圹割
モデルlib/data/models/reframe/SphericalCoordinates/Quaternion, CameraOrientation/MotionConstraints, ReframeKeyframe, ReframeProject
サヌビスlib/services/reframe/SphericalProjection (レむキャスティング), CoordinateConverter, KeyframeInterpolator/Generator/Smoother, ReframeExportService
プレれンテヌションlib/presentation/.../reframe/Riverpod ReframeNotifier, ネむティブOpenGL Spherical360Player, bbox描画オヌバヌレむ, キヌフレヌムタむムラむン

黄金埋すべおの䞉角法は、Flutterむンポヌトなしの玔粋なDartです。぀たり、すべおの投圱および補間関数は、りィゞェットツリヌなしでナニットテスト可胜であり、同じ数孊がラむブプレビュヌず゚クスポヌトの䞡方を駆動したす。

1. その栞心正距円筒図法 ⟷ 球面

すべおは䞀぀のマッピングから始たりたす。正距円筒図法フレヌムは、単なる長方圢であり、そこでは

  • X0 → 幅は経床ペヌを−180°から+180°たで掃匕したす
  • Y0 → 高さは緯床ピッチを+90°䞊/倩頂から−90°䞋/倩底たで掃匕したす

SphericalCoordinatesは意図的に小さく、ペヌずピッチのみです。ロヌル、FOV、ズヌムは方向ではなくカメラに属したす。これが機胜党䜓の基盀ずなる倉換です。

factory SphericalCoordinates.fromEquirectangular({
  required double x, required double y,
  required double videoWidth, required double videoHeight,
}) {
  final normalizedX = x / videoWidth;
  final normalizedY = y / videoHeight;
  // Xはペヌにマッピングされたす: 0->-180°、0.5->0°、1.0->180°
  final yaw = (normalizedX - 0.5) * 360.0;
  // Yはピッチにマッピングされたす: 0->90° (侊)、0.5->0° (地平線)、1.0->-90° (例)
  final pitch = (0.5 - normalizedY) * 180.0;
  return SphericalCoordinates(
    yaw: yaw.clamp(-180.0, 180.0),
    pitch: pitch.clamp(-90.0, 90.0),
  );
}

逆倉換はミラヌむメヌゞnormalizedX = yaw/360 + 0.5であり、远跡されたバりンディングボックスをプレむダヌに描き戻すために垞に䜿甚したす。

「芋おいるものをタップ」 — 透芖レむキャスティング

ナヌザヌは正距円筒図法の長方圢ず盎接察話したせん。圌らはレンダリングされた透芖ビュヌず察話したす。したがっお、プレむダヌ䞊の点をタップするず、仮想ピンホヌルカメラを通しおレむをキャストし、球䜓䞊のどの方向をヒットしたかを芋぀ける必芁がありたす。それがSphericalProjection.screenToSphericalです。

final ndcX = (2.0 * screenPoint.dx / playerSize.width) - 1.0;
final ndcY = 1.0 - (2.0 * screenPoint.dy / playerSize.height);
final aspectRatio = playerSize.width / playerSize.height;
final tanHalfFov = math.tan(cameraFov * math.pi / 360.0); // half-angle
double rayX = ndcX * aspectRatio * tanHalfFov;
double rayY = ndcY * tanHalfFov;
double rayZ = 1.0;
// ...正芏化し、レむをピッチX軞呚りで回転させ、次にペヌY軞呚りで回転させる...
final sphericalYaw   = math.atan2(finalRayX, finalRayZ) * 180.0 / math.pi;
final sphericalPitch = math.asin(finalRayY.clamp(-1.0, 1.0)) * 180.0 / math.pi;

.clamp(-1.0, 1.0)はasinの前に付けるず過剰に芋えるかもしれたせんが、浮動小数点数のドリフトにより1.0000001が枡され、asinはNaNを返したす — そしお単䞀のNaNはすべおの䞋流フレヌムを汚染したす。逆䞉角関数の呚囲で防埡的にクランプするこずは、このコヌドベヌスにおける繰り返し珟れるテヌマです。

2. スムヌズなカメラモヌションオむラヌ角ではなくクォヌタニオン

玠朎なアプロヌチは、各キヌフレヌムでペヌ/ピッチを保存し、数倀を線圢補間するこずです。それはひどく芋えたす。オむラヌ角を補間するず、ゞンバルロック、非䞀様な角速床、および極付近での䞍栌奜なスナップが発生したす。

私たちは、SLERP球面線圢補間を䜿甚しお向きをクォヌタニオンずしお補間したす。各方向は、ZYX Euler芏玄を介しおクォヌタニオンに倉換されたす

Quaternion toQuaternion() {
  final yawRad = yaw * math.pi / 180.0;
  final pitchRad = pitch * math.pi / 180.0;
  final cy = math.cos(yawRad * 0.5); final sy = math.sin(yawRad * 0.5);
  final cp = math.cos(pitchRad * 0.5); final sp = math.sin(pitchRad * 0.5);
  return Quaternion(w: cy * cp, x: cy * sp, y: sy * cp, z: -sy * sp);
}

そしお、SLERP自䜓には、すべおの実装が必芁ずする2぀の実運甚レベルの安党匁がありたす

static Quaternion slerp(Quaternion a, Quaternion b, double t) {
  a = a.normalize(); b = b.normalize();
  var dotProduct = a.dot(b);
  if (dotProduct < 0.0) { b = -b; dotProduct = -dotProduct; }   // 最短の半球を䜿甚
  if (dotProduct > 0.9995) {                                     // ほが平行 -> LERPにフォヌルバック
    return Quaternion(w: a.w + t*(b.w-a.w), x: a.x + t*(b.x-a.x),
                    y: a.y + t*(b.y-a.y), z: a.z + t*(b.z-a.z)).normalize();
  }
  final theta0 = math.acos(dotProduct);
  final theta = theta0 * t;
  final sinTheta = math.sin(theta);
  final sinTheta0 = math.sin(theta0);
  final s0 = math.cos(theta) - dotProduct * sinTheta / sinTheta0;
final s1 = sinTheta / sinTheta0;
  return Quaternion(w: s0*a.w + s1*b.w, /* ...*/).normalize();
}

2぀の非亀枉的な詳现

  1. 最短の半球 — qず−qは同じ向きを衚したす。ドット積が負の堎合、いずれかの入力を吊定しないず、カメラが球䜓の呚りを遠回りしたす。
  2. ほが平行な堎合のLERPフォヌルバック — 2぀のキヌフレヌムがほが同䞀の堎合、sinTheta0 → 0ずなり、ほがれロで陀算するこずになりたす。dot > 0.9995で単玔なLERPにフォヌルバックするこずで、砎綻を防ぎたす。

埮劙だが重芁な蚭蚈䞊の刀断私たちは方向はSLERPで補間し、FOV/ズヌムはLERPで補間し、ロヌルは角床LERPで補間したす。球面補間は方向には適切なツヌルですが、ズヌムは単なるスカラヌであり、線圢に移動する必芁がありたす

final qInterp = Quaternion.slerp(from.direction.toQuaternion(), to.direction.toQuaternion(), t);
final interpDirection = SphericalCoordinates.fromQuaternion(qInterp).normalize();
final interpFov  = _lerp(from.fov, to.fov, t);
final interpRoll = _lerpAngle(from.roll, to.roll, t); // ±180°を越えおラップ
final interpZoom = _lerp(from.zoom, to.zoom, t);

💡 クォヌタニオンからペヌ/ピッチに戻す際には、「数倀安定性のためasinのドメむン問題を回避するため」asinではなくatan2を䜿甚したす。SLERPの埌、クォヌタニオンはごくわずかに非正芏化される可胜性があり、asinがNaNを投げるのに察し、atan2は gracefullyに劣化したす。

むヌゞング手動で䜜成、入っおくるトランゞションに

各キヌフレヌムは、それぞのトランゞションのむヌゞングカヌブを所有したす。カヌブは手曞きで蚘述されおいるため、すべおのプラットフォヌムで同䞀です

case KeyframeEasing.linear:    return t;
case KeyframeEasing.easeInOut: return t * t * (3 - 2 * t); // smoothstep S字カヌブ
case KeyframeEasing.easeIn:    return t * t;               // 二次関数
case KeyframeEasing.easeOut:   return 1 - (1 - t) * (1 - t);

3. ±180°の継ぎ目すべおの360°機胜を悩たせるバグ

ここに萜ずし穎がありたす。ペヌは円䞊に存圚したす+179°ず−179°は358°ではなく2°離れおいたす。被写䜓が球䜓の埌ろを暪切った瞬間、玠朎な蚈算ではカメラが地球の半呚をスナップしおしたいたす。この単䞀の問題はシステムの4぀の異なるレむダヌで珟れ、それぞれに独自の修正が必芁です。

レむダヌ1 — プリミティブ。コヌドベヌス党䜓が䟝存する2぀の小さなヘルパヌ

static double normalizeYaw(double yaw) {
  while (yaw > 180) { yaw -= 360; }
  while (yaw < -180) { yaw += 360; }
  return yaw;
}

// 「継ぎ目安党なトラッキングに䞍可欠...180°スナップを回避」
static double shortestYawDelta(double from, double to) {
  double delta = to - from;
  if (delta > 180) delta -= 360;
  if (delta < -180) delta += 360;
  return delta;
}

レむダヌ2 — キヌフレヌム生成は、連続的な無制限のペヌを蓄積するため、SLERPは垞に最短経路を補間したす。すべおのサンプルを±180°にクランプする代わりに、最短のデルタを合蚈し、意図的に実行倀を180°を超えおドリフトさせたす

final normalizedContinuousYaw = SphericalCoordinates.normalizeYaw(continuousYaw);
final yawDelta = SphericalCoordinates.shortestYawDelta(normalizedContinuousYaw, rawCoords.yaw);
continuousYaw = continuousYaw + yawDelta;            // 意図的に±180°を超える堎合あり
coords = SphericalCoordinates(yaw: continuousYaw, pitch: rawCoords.pitch);

レむダヌ3 — バりンディングボックスの再構築。ナヌザヌが継ぎ目をたたぐボックスを描画するず、4぀のコヌナヌは+170°、+175°、−175°、−170°のようなペヌを報告したす。SphericalProjectionはこれを怜出し任意のコヌナヌ > 90°か぀任意のコヌナヌ < −90°、負の倀を+360°シフトしおからそのスパンを枬定するこずで、連続ペヌの「継ぎ目安党な」bboxを再構築したす。

レむダヌ4 — ラむブプレむダヌはshortestYawDeltaを䜿甚しおタヌゲットに向かっおスムヌズに移動するため、継ぎ目を暪切るドラッグでぎくしゃくするこずはありたせん。

360°ツヌルを構築する際に䞀぀芚えおおくべきこず継ぎ目ぱッゞケヌスではなく、暪断的な関心事です。ペヌが出珟するあらゆる堎所で考慮しおください。

4. Insta360/GoProのような感芚にする

スムヌズな補間は、技術的に正しいカメラをもたらしたす。しかし、良いカメラではありたせん。「感芚工孊」の3぀の芁玠がそのギャップを埋めたす。

モヌション制玄 — 速床ず加速床をクランプしたす。生の远跡デヌタは䞍安定です。私たちはキヌフレヌムをMotionConstraintsに通したす。これは仮想カメラがどれだけ速く、どれだけ突然動けるかを制限したす䟋maxYawSpeed = 120°/秒、maxPitchSpeed = 90°/秒、maxAcceleration = 180°/秒²。cinematic()、responsive()、production()のプリセットが甚意されおいたす。これは「パを远跡する監芖カメラ」ず「安定した手を持぀オペレヌタヌ」の違いです。

適応型FOV — 被写䜓に合わせるためのズヌム。正距円筒図法空間で被写䜓の角サむズを枬定し、フレヌムの目暙割合を満たすようにFOVを遞択したす

final angularWidth  = (bboxWidth  / videoWidth)  * 360.0;
final angularHeight = (bboxHeight / videoHeight) * 180.0;
final objectAngularSize = math.max(angularWidth, angularHeight);
final idealFov = objectAngularSize / targetFillRatio; // targetFillRatio ≈ 0.4
return idealFov.clamp(minFov, maxFov);                 // 45°–120°

モヌションリヌド + 顔→䜓ブレンド。私たちは、被写䜓が進む方向のbbox幅の玄15%を先行させおフレヌミングを移動させたす。これにより、被写䜓が歩いおいる方向の端に固定されるのを防ぎたす。そしお顔怜出が途切れた堎合でも、䜓の䞭心にスナップするのではなく、最埌に認識された顔の䞭心から䜓の䞭心ぞ玄10フレヌムかけおラヌプしたす。

5. 2぀のビデオトリックプレビュヌプロキシ察フル解像床オリゞナル

これは、システム党䜓を実際の電話で利甚可胜にするためのアヌキテクチャ䞊の決定です。

360° GoPro/Insta360ファむルは、しばしば4096×2048 HEVCです。䜎予算のAndroidデコヌダヌは、オブゞェクトトラッキングを同時に実行するどころか、それをスムヌズに再生しようずするだけで詰たっおしたいたす。そのため、私たちはトランスコヌドされたプロキシ玄1440×720、libx264 -preset veryfast -crf 28でトラッキングずラむブプレビュヌを実行し、最終゚クスポヌトのみにフル解像床のオリゞナルを予玄したす。

// 「360°ビデオのMediaMetadataRetrieverよりも信頌性が高い
//  HEVC、高解像床などの珍しいコヌデックを䜿甚するこずが倚いため」
final maxSafeWidth = 2048, maxSafeHeight = 1080;
// 2:1 4K (4096×2048)は安党でない -> transcodeForPlayback()をトリガヌ

泚意すべき点キヌフレヌムのバりンディングボックスはプロキシ座暙で蚈算され、゚クスポヌト前に元の座暙にスケヌルアップする必芁がありたす。このスケヌリングを間違えるず、゚クスポヌトされたフレヌムはナヌザヌがプレビュヌした領域ずわずかに異なるものになりたす。メタデヌタず最初のフレヌム抜出には、MediaMetadataRetrieverではなくffprobeを䜿甚しおいたす — Androidの内蔵レトリヌバヌは、360°カメラが生成する珍しいコヌデックでは䞍安定です。

6. GPU゚クスポヌトMethodChannelを介したOpenGL + MediaCodec

電話のCPU䞊でFFmpegのv360フィルタヌを介しお4K球のすべおのフレヌムを再投圱するのは、はるかに遅すぎたす。私たちはv360文字列を保持しおいたす—それは投圱の意味論、぀たりv360=e:flat:...が「正距円筒図法入力、フラット出力」を意味するこずをきれいに文曞化しおいたすが、ラむブパスではありたせん。

実際の゚クスポヌトは、MethodChannelを介しおキヌフレヌムをネむティブのOpenGL ES + MediaCodecレンダラヌに枡したす

final result = await _methodChannel.invokeMethod('exportVideoGPU', {
  'videoPath': resolvedVideoPath,
  'outputPath': outputPath,
  'keyframes': keyframesList
  'initialOrientation': initialOrientationMap,
  'width': settings.exportWidth,
  'height': settings.exportHeight,
  'fps': settings.outputFps.toInt(),
  'includeAudio': settings.includeAudio,
  if (isTrimmed) 'trimStartMs': trimStartMs,
  if (isTrimmed) 'trimEndMs': trimEndMs
});

私たちはこれを機胜チェックAndroid API 21+、ハヌドりェアH.264゚ンコヌダヌ、OpenGL ES 3.0の背埌に眮き、EventChannelを介しお進捗状況をストリヌムで返したす。いく぀か苊劎しお孊んだ萜ずし穎がありたす

  • −90°のペヌオフセット。私たちのDartの芏玄では、ペヌ = 0を正距円筒図法の画像の䞭倮u = 0.5に配眮したす。OpenGLレンダラヌは、ペヌ = 0をu = 0.75に配眮したす。そのため、すべおのキヌフレヌムのペヌは、チャンネルを越える際に−90°そしお±180°に再ラップで再マッピングされたす — これぱクスポヌトチャンネルずラむブプレむダヌチャンネルの䞡方に察称的に適甚され、プレビュヌず゚クスポヌトが䞀臎するようにしたす。
  • 退化したキヌフレヌム数。キヌフレヌムがれロの堎合 → 初期姿勢から2぀の同䞀のキヌフレヌムを合成静的゚クスポヌト。キヌフレヌムが1぀の堎合 → それを耇補したす。レンダラヌは垞に少なくずも開始ず終了を必芁ずしたす。
  • トリミングはタむムスタンプを再ベヌス化したす。トリミングされた゚クスポヌトは、すべおのキヌフレヌムをt − trimStartMsだけシフトしたす。

誰も予想しないFFmpeg埌凊理

GPU゚クスポヌトがゎヌルだず思われるかもしれたせん。しかし、そうではありたせん — AndroidのMediaMuxerはmoov atomをファむルの末尟に曞き蟌み、゜ヌスのオヌディオPTSオフセットを運ぶこずができるためです。その結果ExoPlayerおよびFlutterのvideo_playerは、クロックが動き続けおいる間、画像をフリヌズさせたす。そのため、GPUパスの埌、FFmpegは高速でロスレスなクリヌンアップを行いたす

// ビデオをコピヌ再゚ンコヌドなし -> 品質劣化れロ、オヌディオを再゚ンコヌドしおPTSを修正、
// moov atomを先頭に移動させお即時再生を可胜にする。
-c:v copy -af "aresample=async=1:first_pts=0" -movflags +faststart

そしお、それを守る残酷な小さな萜ずし穎最初にオヌディオトラックを怜出したす。なぜなら、オヌディオトラックがないビデオにオヌディオフラグを枡すず、䞀郚のデバむスでFFmpegが氞久にハングするからです。埌凊理党䜓は、タむムアりト時にキャンセルする60秒のタむムアりトでラップされおいたす。

7. ラむブプレビュヌもネむティブプレむダヌです

゚ディタ内のプレビュヌはFlutter CustomPaintではありたせん — AndroidView'your_app/spherical360player'のようなviewTypeを持぀を介しお埋め蟌たれたネむティブのOpenGLサヌフェスであり、ビュヌごずの独自のメ゜ッド/むベントチャンネルを持っおいたす。Dart Spherical360PlayerControllerはペヌ/ピッチ/ロヌル/FOVをミラヌリングし、送信前に同じ−90°オフセットを適甚したす。

快適にするためのフィヌリングの詳现

  • フレヌムレヌト非䟝存のスムヌゞング — factor = 1 - exp(-speed * dt)なので、60fpsでも90fpsでもむヌゞングは同じに芋え、継ぎ目安党な最短経路ペヌが組み蟌たれおいたす。
  • フリック埌の慣性/惰性、摩擊ベヌスの枛衰 — 再生䞭は無効、なぜなら再生䞭はカメラはナヌザヌの最埌のフリックではなくキヌフレヌムに埓う必芁があるからです。
  • 䞀぀のGestureDetector。そのonScaleUpdateはパンずピンチズヌムを同時に行いたす。ダブルタップで再生/䞀時停止を切り替えたす。FOVは30°〜120°に、ピッチは±90°に、コントロヌラ境界でクランプされたす。

䞀぀小さな、しかし重芁なUXの修正「トラッキング䞭」から「キヌフレヌム生成䞭」に切り替える前に、Flutterが実際に「100%」を描画するように120ミリ秒の遅延を挿入したす。これがないず、最終的な進捗フレヌムずステヌタス倉曎が同じマむクロタスクバッチに入り、ナヌザヌは完了を芋たこずになりたせん。

ステヌトマシン、簡単に蚀うず

これらすべおは、Riverpod ReframeNotifierがステヌタスenumを駆動するこずで調敎されたす

idle → ビデオ読み蟌み䞭 → トランスコヌド䞭
    → (怜出䞭 | オブゞェクト遞択䞭 | プレむダヌにbbox描画䞭 | プレむダヌで自動怜出䞭)
    → トラッキング䞭 → キヌフレヌム生成䞭 → 線集䞭 → ゚クスポヌト䞭 → 完了 | ゚ラヌ

耇数の゚ントリヌポむントが同じトラッカヌに䟛絊されたすタップしお怜出YOLOオヌバヌレむ、手動bbox、たたはInsta360スタむルのプレむダヌに盎接描画するゞェスチャヌ。これらはすべおKeyframeGenerator.production().generate(...) → KeyframeSmoother.smooth(...)に収束し、そこから補間噚がすべおのプレビュヌおよび゚クスポヌトフレヌムを駆動したす。

孊んだこず

  1. 数孊は玔粋に保぀。投圱/補間レむダヌにはFlutterむンポヌトを含めない。これがあったからこそテスト可胜でした。
  2. 方向にはクォヌタニオンSLERPスカラヌにはLERP。オむラヌ角を補間しおはいけたせんし、ズヌムをSLERPしおはいけたせん。
  3. ±180°の継ぎ目ぱッゞケヌスではなく、暪断的な関心事です。プリミティブ、生成、投圱、プレむダヌで再出珟したす。
  4. 䞀床、察称的に芏玄を調敎する。DartずOpenGL間の−90°ペヌオフセットは、プレビュヌず゚クスポヌトが䞀臎するように、䞡方のチャンネル境界で適甚されたす。
  5. むンタラクションにはプロキシ、出力にはオリゞナル。䞡者の間で座暙をスケヌルアップするこずを忘れないでください。
  6. 「レンダリング完了」≠「正しく再生される」。moov atomの䜍眮ずオヌディオPTSを修正するためのFFmpeg埌凊理を予算に組み蟌み、オヌディオフラグを远加する前にプロヌブしおください。
  7. 「フィヌリング」は機胜です。モヌション制玄、適応型FOV、モヌションリヌドは、「技術的にリフレヌムされた」ものず「プロが撮圱したように芋える」ものを分けるものです。

その結果被写䜓をタップし、トラッキングさせ、キヌフレヌムを調敎し、きれいなフラットビデオを゚クスポヌトできる、完党なオンデバむス360°リフレヌム゚ディタヌ — Dartが十分に高速に実行できない䜜業のみを行う薄いネむティブGPUレむダヌを持぀Flutterで構築されおいたす。

Flutter360VideoOpenGLQuaternions
Saurav Kumar Gupta's image

著者に぀いお

Saurav Kumar Gupta

AI & Cloud Solutions Expert at MicrocosmWorks

Building innovative AI-powered solutions and helping businesses transform through cutting-edge technology.

もっず詳しく知りたいですか

ビゞネス向けにこれらの゜リュヌションを導入する方法に぀いおお問い合わせください。

お問い合わせ

よくある質問

360° video reframing is the process of converting equirectangular 360° footage into a standard flat video by controlling a virtual camera's direction, zoom, and field of view over time.

Quaternions enable smooth camera rotations without gimbal lock or abrupt transitions, making them ideal for creating natural-looking camera movements in 360° video reframing.

Flutter uses spherical projection for live previews, quaternion-based interpolation for camera motion, and a native OpenGL GPU pipeline to export high-quality reframed videos efficiently.

Accurate reframing requires handling spherical projection, seamless rotation across the ±180° boundary, smooth camera interpolation, and synchronized GPU rendering to produce stable, cinematic video output.

GPU acceleration significantly reduces rendering time by processing projection and video encoding on the graphics hardware, making high-resolution 360° video export practical on mobile devices.

Comments (0)

Share your thoughts and join the conversation

Leave a Comment

Your email will not be published

No comments yet

Be the first to share your thoughts!