비디오 플레이어
1) BoxDecoration
- 컨테이너에서 그라데이션 색상을 만들어주는 gradient 속성을 지정
- LinearGradient 클래스를 사용해서 시작색과 끝색을 지정해서 그라데이션을 설정
// Container의 배경색을 그라데이션으로 변경 타입 BoxDecoration
BoxDecoration getBoxDecoration() {
return const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFF2A3A7C), // 시작
Color(0xFF000118), // 끝
],
),
);
}
2) XFile
- ImagePicker를 사용해서 이미지나 동영상을 담는 데이터 타입
class CustomVideoPlayer extends StatefulWidget {
// 선택한 동영상 저장 변수
// XFile은 ImagePicker로 영상 또는 이미지 선택시 반환되는 타입
final XFile video;
const CustomVideoPlayer({
super.key,
required this.video,
});
3) videoController
- 비디오 컨트롤러를 파일경로로 생성하고 초기화
// 비디오 컨트롤러 선언용
initializeController() async {
final videoController = VideoPlayerController.file(
// 네임드 생성자를 사용해서 만듦
File(widget.video.path),
);
// 비디오 컨트롤러를 위에서 생성자로 만든 다음 여기서 초기화
await videoController.initialize();
// 비디오 컨트롤러에 동작이 있을 때마다 videoControllerListner 메서드 동작
videoController.addListener(videoControllerListner);
setState(() {
// 위에서 만들어둔 컨트롤러를 대입
this.videoController = videoController;
});
}
4) didUpdateWidget
- 매개변수가 변화할 때 변경전 위젯이랑 변경후 위젯을 비교해서 다른 경우 다시 비디오 컨트롤러 초기화 메서드를 실행
@override
// covariant 키워드는 CustomVideoPlayer 클래스의 상속된 값도 허가해줌
// 위젯은 매개변수값이 변경될 때 폐기되고 새로 생성됨 그 때 폐기되는 위젯이 oldWidget
void didUpdateWidget(covariant CustomVideoPlayer oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.video.path != widget.video.path) {
initializeController();
}
}
영상통화
1) WebRTC
- 웹 브라우저 기반 영상, 음성, 파일 등 공유하는 기능을 제공
- 각 클라이언트 간의 연결을 하고 영상이나 음성들이 해당 서버를 거쳐서 각 클라이언트에게로 전송됨
2) permission handler
- 휴대폰 팝업으로 각 리소스 권한 요청하는 걸 제어하는 라이브러리
- request 메서드로 각 리소스에 대한 팝업창을 띄운 후 권한 여부를 반환
Future<bool> init() async {
final resp = await [Permission.camera , Permission.microphone].request();
final cameraPermission = resp[Permission.camera];
final micPermission = resp[Permission.microphone];
if(cameraPermission != PermissionStatus.granted || micPermission != PermissionStatus.granted){
throw '카메라 또는 마이크 권한이 없습니다';
}
return true;
}
3) FutureBuilder
- future 매개변수에 있는 값에 따라 랜더링
- build는 위젯 생성시 즉시 실행된다. 권한에 따라 화면을 달리 보여주기 때문에 해당 위젯을 써서 요청을 하고 비동기적으로 기다림
- AsyncSnapshot의 값이 변경될 때마다 builder함수가 재실행
// 보통 build가 먼저 실행되니까 FutureBuilder로 이거 실행시킨 다음 랜더링 하도록 세팅
Future<bool> init() async {
final resp = await [Permission.camera, Permission.microphone].request();
final cameraPermission = resp[Permission.camera];
final micPermission = resp[Permission.microphone];
if (cameraPermission != PermissionStatus.granted ||
micPermission != PermissionStatus.granted) {
throw '카메라 또는 마이크 권한이 없습니다';
}
return true;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('LIVE'),
),
body: FutureBuilder( // future기반으로 랜더링
future: init(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Center(
child: Text(snapshot.error.toString()),
);
}
if (snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
return Center(
child: Text('모든 권한 있음'),
);
},
),
);
}
4) Navigator
- 화면을 이동시킴
ElevatedButton(
onPressed: () {
// 위젯트리 가장 가까이 있는 Navigator 가지고옴 보통 MaterialApp으로 감싸면 최상위 Navigator가 자동 생성
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => CamScreen(),
),
);
},
child: Text('입장하기'),
),
이 글은 골든래빗 《Must Have 코드팩토리의 플러터 프로그래밍 2판》의 스터디 내용 입니다.
'프로그래밍 > 플러터' 카테고리의 다른 글
16장 17장 (0) | 2024.03.27 |
---|---|
Google API & Photo (0) | 2024.03.20 |
TabBarView & BottomNavigation (0) | 2024.03.04 |
Theme 설정 및 Dialog (0) | 2024.03.03 |
PageView와 Timer (1) | 2024.02.24 |
하고 싶은 걸 하고 되고 싶은 사람이 되자!
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!