import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:tiktok_clone/constants/gaps.dart';
import 'package:tiktok_clone/constants/sizes.dart';
class VideoRecordingScreen extends StatefulWidget {
const VideoRecordingScreen({super.key});
State<VideoRecordingScreen> createState() => _VideoRecordingScreenState();
}
class _VideoRecordingScreenState extends State<VideoRecordingScreen> {
bool _hasPermission = false; // 카메라 및 마이크 접근 권한의 상태를 저장합니다.
bool _isSelfieMode = false; // 현재 카메라가 셀피 모드인지 아닌지를 나타냅니다.
late FlashMode _flashMode; // 현재 설정된 플래시 모드를 저장합니다.
late CameraController _cameraController; // 카메라의 상태와 제어를 담당합니다.
// 카메라를 초기화하는 함수입니다.
Future<void> initCamera() async {
final cameras = await availableCameras();
if (cameras.isEmpty) {
return;
}
_cameraController = CameraController(
cameras[_isSelfieMode ? 1 : 0], // 셀피 모드 여부에 따라 카메라를 선택합니다.
ResolutionPreset.ultraHigh, // 최대 해상도로 설정합니다.
);
await _cameraController.initialize();
_flashMode = _cameraController.value.flashMode; // 현재 플래시 모드를 초기화합니다.
}
// 카메라 및 마이크 접근 권한을 요청하는 함수입니다.
Future<void> initPermissions() async {
final cameraPermission = await Permission.camera.request();
final micPermission = await Permission.microphone.request();
// 접근이 거부되었는지 확인합니다.
final cameraDenied = cameraPermission.isDenied || cameraPermission.isPermanentlyDenied;
final micDenied = micPermission.isDenied || micPermission.isPermanentlyDenied;
if (!cameraDenied && !micDenied) {
_hasPermission = true;
await initCamera(); // 권한이 승인되면 카메라를 초기화합니다.
setState(() {});
}
}
void initState() {
super.initState();
initPermissions();
}
// 셀피 모드를 전환하는 함수입니다.
Future<void> _toggleSelfieMode() async {
_isSelfieMode = !_isSelfieMode;
await initCamera();
setState(() {});
}
// 플래시 모드를 설정하는 함수입니다.
Future<void> _setFlashMode(FlashMode newFlashMode) async {
await _cameraController.setFlashMode(newFlashMode); // 새로운 플래시 모드로 설정합니다.
_flashMode = newFlashMode; // 상태를 업데이트합니다.
setState(() {});
}
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: SizedBox(
width: MediaQuery.of(context).size.width,
child: !_hasPermission || !_cameraController.value.isInitialized
? Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text("Initializing...", style: TextStyle(color: Colors.white, fontSize: Sizes.size20)),
Gaps.v20,
CircularProgressIndicator.adaptive()
],
)
: Stack(
alignment: Alignment.center,
children: [
CameraPreview(_cameraController), // 카메라 미리보기를 표시합니다.
Positioned( // 플래시 모드 조절 버튼을 배치합니다.
top: Sizes.size20,
right: Sizes.size20,
child: Column(
children: [
IconButton(
color: Colors.white,
onPressed: _toggleSelfieMode, // 셀피 모드 전환 버튼
icon: const Icon(Icons.cameraswitch),
),
Gaps.v10,
// 플래시 모드 설정 버튼들입니다. 현재 플래시 모드에 따라 아이콘 색상이 변경됩니다.
IconButton(
color: _flashMode == FlashMode.off ? Colors.amber.shade200 : Colors.white,
onPressed: () => _setFlashMode(FlashMode.off),
icon: const Icon(Icons.flash_off_rounded),
),
Gaps.v10,
IconButton(
color: _flashMode == FlashMode.always ? Colors.amber.shade200 : Colors.white,
onPressed: () => _setFlashMode(FlashMode.always),
icon: const Icon(Icons.flash_on_rounded),
),
// 이하 동일한 패턴으로 플래시 모드를 설정하는 버튼들이 계속됩니다.
],
),
),
],
),
),
);
}
}
이 코드에서 플래시 모드와 관련된 로직은 사용자가 카메라 앱 내에서 플래시의 작동 방식을 조절할 수 있게 해줍니다. 이는 특히 다양한 조명 조건에서 비디오 또는 사진을 촬영할 때 유용합니다. 여기서 사용된 주요 기능과 절차를 요약하면 다음과 같습니다:
카메라 컨트롤러 초기화: _cameraController
는 CameraController
객체를 사용해 초기화되며, 이는 선택된 카메라와 해상도 프리셋(ResolutionPreset.ultraHigh
)을 설정합니다. 이 과정에서 _flashMode
도 현재 카메라 컨트롤러의 플래시 모드 값으로 초기화됩니다.
권한 요청: initPermissions
함수는 카메라와 마이크 사용에 필요한 사용자 권한을 요청합니다. 모든 권한이 승인되면 카메라가 초기화됩니다.
셀피 모드 전환: _toggleSelfieMode
함수는 _isSelfieMode
의 값을 토글하여 셀피 모드를 전환하고, 카메라를 재초기화합니다. 이는 사용자가 전면 카메라와 후면 카메라를 전환할 수 있게 합니다.
플래시 모드 설정: _setFlashMode
함수는 새로운 플래시 모드(FlashMode
)를 인자로 받아 _cameraController
를 통해 해당 모드로 설정합니다. 이 설정은 비디오 또는 사진 촬영 시 플래시의 동작 방식을 결정합니다.
UI 상호작용: 사용자는 UI 상의 아이콘 버튼을 통해 플래시 모드를 FlashMode.off
, FlashMode.always
, FlashMode.auto
, FlashMode.torch
중에서 선택할 수 있습니다. 각 버튼은 해당 플래시 모드로 설정하는 기능을 수행하며, 선택된 플래시 모드에 따라 아이콘의 색상이 변경되어 현재 설정을 시각적으로 표시합니다.
이 로직을 통해 사용자는 앱 내에서 플래시 모드를 동적으로 조절할 수 있으며, 이는 어두운 환경에서의 촬영이나 특정 효과를 주기 위한 촬영에서 유용하게 사용될 수 있습니다.