최근 프로젝트에서 Flutter 영상 플레이어 관련해서 꽤 골치 아픈 문제를 겪었다.
초반에는 Flutter 기본 video_player 패키지를 썼는데, ios에서는 잘 재생되었던 영상이 aos로 실행해 보니 예상보다 버벅거림이 심했고, 특히 Android 에뮬레이터나 저사양 기기에서 프레임 드롭이 눈에 띄게 많았다.
그래서 결국 커스텀 컨트롤, 로딩 속도, 안정성 등에서 나은 성능을 보인
👉 better_player_plus 패키지로 전환하게 됐다.
❗ VideoPlayer의 한계
- 영상 로딩 속도가 느림
- 자주 초기화가 꼬이거나, 컨트롤이 불안정함
- 커스텀 UI와의 연결이 불편
- 고해상도 영상에서 프레임 드랍 발생
✅ BetterPlayer로 전환한 이유
- 자체 버퍼링 및 컨트롤러 관리가 훨씬 안정적
- 다양한 설정 옵션 (fit, aspectRatio, autoPlay, controlsConfiguration 등)
- 영상 동기화 및 커스텀 제어가 훨씬 수월
- HLS 스트리밍 등 고급 기능 내장
비율 문제: 9:16 영상이 16:9로 잘려 보이는 현상
BetterPlayer를 쓰면서 또 하나의 이슈가 있었는데,
바로 세로(9:16) 영상이 강제로 16:9처럼 잘려 보이는 현상이었다.
이유는 간단했다:
BetterPlayer는 기본적으로 aspectRatio를 고정해 두면 그 비율에 맞춰 영상의 보이는 영역을 잘라서 보여준다.
만약 영상 자체의 실제 비율과 다르면, 검은 여백이 생기거나 영상이 클리핑 된다.
해결 방법: aspectRatio는 null, 대신 직접 비율 계산
BetterPlayerController(
BetterPlayerConfiguration(
aspectRatio: null, // 직접 처리할 것!
fit: BoxFit.cover, // 꽉 채우는 용도
controlsConfiguration: BetterPlayerControlsConfiguration(showControls: false),
),
)
그리고 UI에서 영상의 actual aspect ratio 값을 기반으로 직접 크기를 조절한다.
- 세로 영상은 Alignment.topCenter로 정렬해서 위쪽부터 보여주고
- 가로 영상은 Alignment.center로 정렬해서 정중앙에 표시
- 여백 없이 꽉 차도록 width/height를 수학적으로 계산
controller.videoPlayerController?. value.aspectRatio를 활용해서
실제 영상의 비율을 얻고, 그에 맞춰 Container 크기를 조정한다.
화면 회전 대응 (OrientationBuilder 활용)
추가로, 기기를 회전했을 때도 비율이 어색해지지 않게 하려면
OrientationBuilder를 써서 자동으로 화면에 맞게 다시 렌더링 하는 것이 좋다.
OrientationBuilder(
builder: (context, orientation) {
final isPortrait = orientation == Orientation.portrait;
final aspectRatio = controller.videoPlayerController?.value.aspectRatio ?? 9/16;
controller.setOverriddenAspectRatio(aspectRatio);
return Container(
alignment: isPortrait ? Alignment.topCenter : Alignment.center,
child: BetterPlayer(controller: controller),
);
},
);
마무리
video_player는 간단한 작업에는 적당하지만, 고화질 영상이나 복잡한 제어에는 성능 한계가 명확하다.
better_player_plus는 안정성과 커스터마이징에 훨씬 강하다.
영상이 잘려 보이는 문제는 aspectRatio, fit, 그리고 직접 계산한 width/height로 해결 가능하다.
기기 회전은 OrientationBuilder로 반응형 처리 가능.
'개발 > Android' 카테고리의 다른 글
[Kotlin] Firebase Realtime Database에서 리스트 형태로 데이터 저장 및 조회하는 방법 (0) | 2025.04.23 |
---|---|
[Flutter] Flutter에서 ref.invalidate() 사용 시 새로고침 오류 해결하기 (0) | 2025.04.21 |
[Flutter 오류 해결] Gradle & Java 버전 호환 이슈 해결 방법 (feat. Java 21 → 17 다운그레이드) (1) | 2025.04.17 |
[Flutter] Riverpod 상태관리 - ConsumerStatefulWidget 가이드 (0) | 2025.04.02 |
[Flutter] Riverpod 상태관리 - watch vs read 차이 (0) | 2025.04.02 |