推しアイデア
登録した写真をARで認識し,紐づいた動画を重ねて再生することで,思い出をより鮮明に思い起こすことができる
―
登録した写真をARで認識し,紐づいた動画を重ねて再生することで,思い出をより鮮明に思い起こすことができる
アルバムとか見ながら,「この時あんなことあったな」ってなるのを,動画として紐づけて保存できたら便利なのでは
・写真とったら撮影時の5秒前が動画として保存される ・ギャラリーのスクロールの慣性 ↑ 意外と実装が大変
⬇️こんな感じ
void panInertia(double translationXIncrement) { // 動作が安定せず,回転量が大きい場合は処理を終了 if (translationXIncrement.abs() > 0.3) { return; } // 減速率を回転量の変化量の変化量の逆数に設定 double decelerationRatio = 0.001; double lastIncrementValue = translationXIncrement; final isMinus = translationXIncrement < 0; // 0.1秒ごとに回転させて,回転量を減速率に応じて変更 int cout = 0; Timer.periodic(const Duration(milliseconds: 50), (timer) { // 回転量が小さくなったら終了 if (isMinus) { if (lastIncrementValue > -0.01) { timer.cancel(); } } else { if (lastIncrementValue < 0.01) { timer.cancel(); } } // 中心のアンカーノードを回転 final oldCenterAnchorAngleX = centerAnchorNode.eulerAngles.x; centerAnchorNode.eulerAngles = vector.Vector3(oldCenterAnchorAngleX + lastIncrementValue, 0, 0); // 画像ノードを回転 for (final (idx, pictureNode) in pictureNodes.indexed) { final oldPictureNode = pictureNode.eulerAngles; final newNodeAngleX = centerAnchorNode.eulerAngles.x - idx * (pi / (widget.videoPictures.length / 2)); pictureNode.position = vector.Vector3( centerAnchorNode.position.x - r / 2 * sin(newNodeAngleX), centerAnchorNode.position.y, centerAnchorNode.position.z - r / 2 * cos(newNodeAngleX), ); pictureNode.transform.rotateY(newNodeAngleX - oldPictureNode.x - pi); } // 回転量を減速 if (isMinus) { lastIncrementValue += decelerationRatio; } else { lastIncrementValue -= decelerationRatio; } // decelerationRatio = lastIncrementValue.abs() * 0.2; // 減速率を減少 decelerationRatio *= (1 - cout * cout * 0.001); decelerationRatio = max(decelerationRatio, 0.005); cout++; }); }
写真と動画同時に撮るやつ 要件 ・ 写真を撮影する5秒前の様子を長押しすると見れる ・ ライブラリから写真と動画を選択できる
使ったライブラリ ・ カメラから撮影:camera ・ ライブラリから選択:image_picker ・ 5秒前の動画取得:ffmpeg_kit_flutter
難しかったこと ・ ライブラリから選択の制御 写真・動画一枚づつ取得する非同期処理と、バックグラウンドで動いてるカメラ処理の非同期的な制御がむずかった
・ 5秒前の動画の取得 ffmpeg_kit_flutterは、コマンドベースで動画編集するので、そのコマンドの調節がむずかった
Future<void> trimLastFiveSeconds(String moviePath) async { String time = "5"; // 5秒前の開始時間を計算 String startTime = await calculateStartTime(moviePath); // FFmpegKitを使用して動画をトリミング String command = "-y -i $moviePath -ss $startTime -t $time -c copy $outputPath"; await FFmpegKit.execute(command).then((session) async { final returnCode = await session.getReturnCode(); if (returnCode!.isValueSuccess()) { print("Video trimmed successfully"); } else { print("Failed to trim video"); } }); }
・ 迫り来るスパゲッティコードの恐怖 flutter初めてすぎて気にする余裕ない、バグ修正きつい。
後進育成を意識してシンプルな設計と実装を心がけました おべんきょうになったね
https://www.youtube.com/playlist?list=PLiOXM0FsTXiq7XQyU_0zwY4euiVo1JhP7
https://github.com/scla-sagauniv/last-tamushun-app