키치하고 기여운 내 앱~~
Agora.io Real-Time Voice and Video Engagement
The Real-Time Engagement Platform for meaningful human connections.People engage longer when they see, hear, and interact with each other. With Agora, you can embed vivid voice and video in any application, on any device, anywhere.
www.agora.io
일반적으로 WebRTC 기능 사용하지만 프론트엔드 입장에서 요점에 부합하게 공부하기 위해 Agora 라는 중계 서버 API를 사용했다
(매 달 일정 시간 사용 무료)
회원가입하고 프로젝트 만들어 토큰 받아준다
Agora app id, Channel name, Token 이렇게 세 개가 필요하다
이 값들은 변수로 가져다쓰기 쉽게 lib/const/agora.dart 에 저장해주었다
const APP_ID = "your app id";
const CHANNEL_NAME = "your channel id";
const TEMP_TOKEN = "yout temp token";
asset에 원하는 /img와 /font 를 넣고
pubspec.yaml 에 넣어준 asset 데이터를 정의해준다
권한관리
PermissionStatus Class
denied
: 권한 거절된 상태
다시 request() 이용해 권한 요청할 수 있다
권한을 한 번도 요청한 적 없으면 기본값인 거절로 설정된다
granted
: 권한 허가된 상태
restricted
: iOS에서만 해당되는 상태
권한이 제한되어 있을 때 설정되는 상태
ex) 청소년, 자녀 보호 기능
limited
: iOS에서만 해당되는 상태
제한적인 권한이 있을 때 해당된다
permanentlyDenied
: 권한 거절된 상태
Denied 상태와 다른 점은 다시 request() 실행해서 앱에서 권한 요청할 수 없고
설정 앱으로 이동해서 사용자가 직접 권한 허가해야한다
홈스크린
로고 그림자
BoxDecoration 클래스의 boxShadow 매개변수에 원하는 만큼 그림자를 BoxShadow 클래스로 제공해 구현한다
가운데 이미지
버튼
버튼 누르면 CamScreen 페이지로 넘어갈 수 있다
(홈스크린 캡쳐 이미지에는 'GO!' 라고 써있지만 실제 코드에는 'Enter Channel'로 작성했다)
캠스크린
영상통화 기능 구현하기
영상통화 하려면 카메라와 마이크 권한이 필요하다
init() 으로 필요한 기능 받아주기
권한 가져오는 작업은 비동기 프로그래밍이 필요하다
-> 함수를 async로 지정해준다
권한 잘 가져왔을 땐 true값 반환해주고, 문제 있으면 메시지와 함께 에러 던지는 로직 작성한다
FutureBuilder의 ConnectionState 및 캐싱
ConnectionState.none
: 비동기 함수 제공하지 않은 상태
ConnectionState.waiting
: 비동기 함수가 아직 아무런 값 반환하지 않은 상태(실행은 되었지만 끝나지 않은 상태. 아직 로딩중이라고 볼 수 있다)
ConnectionState
: FutureBuilder에서는 사용되지 않고 StreamBuilder에서만 사용된다
Stream이 실행되고 있는 상태를 표현한다
ConnectionState
: 요청이 끝난 상태 의미
에러가 났던 데이터값이 반환된 함수의 실행이 끝나면 반환되는 상태
캐싱(caching)
데이터를 일시적으로 저장하고 기억하는 것
Agora API 활성화
1. 아고라 RtcEngine 활성화(각종 이벤트 받을 수 있는 콜백함수도 설정)
2. RtcEngine 통해 사용하는 핸드폰 카메라 활성화
3. 미리 받아둔 아고라 API 상수값 사용해 testChannel에 입장
engine값이 null인지 확인하고 null이면 새로운 engine 생성하는 로직 실행한다
RtcEngine에 이벤트 콜백 함수들을 등록하는 함수 작성한다
RtcEngineEventHandler class 사용하면 된다
onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
print("You have entered the channel. uid: ${connection.localUid}");
setState(() {
uid = connection.localUid;
});
},
채널에 입장한 상태면 uid 변수에 내 고유 id를 기억해둔다
connection
영상통화 정보에 관련된 값
connection.localUid로 내 id 가져올 수 있다
elapsed
joinChannel 실행 한 후 콜백이 실행되기 전까지 걸린 시간
onLeaveChannel: (RtcConnection connection, RtcStats stats) {
print("You have left the channel.");
setState(() {
uid = null;
});
},
내가 채널에서 나갔을 때 실행되는 콜백 함수
채널에서 나갔으니 uid를 null로 변환한다
onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {
print("Other User has entered the channel. otherUid: $remoteUid");
setState(() {
otherUid = remoteUid;
});
},
remoteUid
상대방 고유 id
elapsed
내가 채널을 들어왔을 때부터 상대가 들어올 때까지 걸린 시간
await engine!.enableVideo();
await engine!.startPreview();
카메라 활성화
await engine!.joinChannel(token: TEMP_TOKEN, channelId: CHANNEL_NAME, uid: 0, options: options);
채널 입장
내 핸드폰이 찍는 화면 렌더링
uid가 null이 아닐 때는 채널에 입장한 상태
-> AgoraVideoView의 controller 매개변수에 VideoViewController() 입력해 내 핸드폰에서 찍는 화면 보여준다
renderMainView
상대 핸드폰에서 찍는 화면 보여준다
나가기 버튼
Navigator.of(context).pop();
pop() 이용해 나가기 구현하기
remote uid can not be null or 0 에러 뜨는데 아래처럼 바꿔주니까 됐다
int? uid = 0; //화상채팅 채널 접속했을 때 내 ID, 디폴트는 0
int? otherUid = 0; //상대 ID
int? uid; // 화상채팅 채널 접속했을 때 내 ID, 디폴트는 null
int? otherUid; // 상대 ID
The changes made include removing the initial values for uid and otherUid, safely accessing uid and otherUid with the null-aware operator !, and correctly updating otherUid in the event handlers. These updates should resolve the "remote uid can not be null or 0" error and ensure the video call integration works as expected.
https://webdemo.agora.io/basicVideoCall/index.html
Basic Video Call -- Agora
webdemo.agora.io
Agora에서 제공해 주는 Basic Video Call 페이지에 app id 등 입력해주면
제대로 앱이 동작하는 걸 볼 수 있다
페이지에서 leave 버튼 눌러주면 앱에서도 영상이 나오지 않는다
(There are no users in the channel.)
'CS > Flutter | Dart' 카테고리의 다른 글
캘린더 일정관리 앱 #2 (12) | 2023.08.17 |
---|---|
캘린더 일정관리 앱 #1 (5) | 2023.08.14 |
StreamBuilder (0) | 2023.08.07 |
FutureBuilder (0) | 2023.08.07 |
출석체크 앱 (0) | 2023.08.05 |