본문 바로가기
프로그래밍/Flutter-Dart

[Flutter] Flutter Video Player

by 채연2 2021. 3. 16.

 

 

 

 

 

* VideoPlayer

 

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  video_player:

 

 

Android-/android/app/src/main/AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application ...>
        
    </application>

    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

 

 

iOS-/ios/Runner/Info.plist

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

 

 

320x100

 

VideoPlayerController 생성 및 초기화

1. StatefulWidget, State class 생성

2. State class에 VideoPlayerController 저장하기 위한 변수 추가

3. State class에 VideoPlayerController.initialize로부터 반환되는 Future 저장하기 위한 변수 추가

4. initSate method에서 controller 생성 및 초기화

5. dispose method에서 controller dispose

class VideoPlayerScreen extends StatefulWidget {
  VideoPlayerScreen() : super();

  // createState() : tree의 지정된 위치에서 이 widget의 변경 가능한 상태 생성
  @override
  _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  VideoPlayerController _controller;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    // VideoPlayerController를 저장하기 위한 변수를 생성.
    // VideoPlayerController : asset, file, network 등 영상들을 제어하기 위해 다양한 생성자 제공.
    // _controller = VideoPlayerController.asset('assets/videos/butterfly.mp4'); //file play
    _controller = VideoPlayerController.network(
      'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4', //live play
    );

    // initialize() : 지정된 dataSource 열고 비디오에 대한 metadata load
    // 컨트롤러를 초기화하고 추후 사용하기 위해 Future를 변수에 할당.
    _initializeVideoPlayerFuture = _controller.initialize();

    // 비디오를 반복 재생하기 위해 컨트롤러를 사용.
    _controller.setLooping(true);

    super.initState();
  }

  @override
  void dispose() {
    // 자원을 반환하기 위해 VideoPlayerController dispose.
    _controller.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    ...
  }
}

 

 

VideoPlayer 화면에 보여주기

- video_player plugin : VideoPlayerController에 의해 초기화된 영상 보여주기 위해 VideoPlayer Widget 제공

- 영상 제대로된 비율 보여지도록 VideoPlayer Widget을 AspectRatio Widget에 넣어줌

- _initializeVideoPlayerFuture가 완료된 후 VideoPlayer 보여줘야 함

   ▶ FutureBuilder 사용하여 초기화 진행되는 동안 로딩 스피너 보여줄 수 있음

// FutureBuilder : VideoPlayerController가 초기화 진행하는 동안 로딩 스피너를 보여주기 위함
FutureBuilder(
   future: _initializeVideoPlayerFuture,
   builder: (context, snapshot) {
      // ConnectionState : 비동기 계산에 대한 연결 상태
      if (snapshot.connectionState == ConnectionState.done) {
         // VideoPlayerController 초기화 끝나면, 제공된 데이터 사용하여 VideoPlayer 종횡비 제한.
         return AspectRatio(
            aspectRatio: _controller.value.aspectRatio,
            // 영상 보여주기 위해 VideoPlayer 위젯 사용.
            child: VideoPlayer(_controller),
         );
      } else {
         // 만약 VideoPlayerController가 여전히 초기화 중이라면, 로딩 스피너를 보여줌.
         return Center(child: CircularProgressIndicator());
      }
   },
)

 

 

영상 재생 및 일시 중지

- 재생 : VideoPlayerController가 제공하는 play() method 호출

- 일시 중지 : pause() method 호출

FloatingActionButton(
   onPressed: () {
      // 재생/일시 중지 기능을 setState에 넣음. 아이콘 변경 위함
      setState(() {
         // 영상 재생 중이라면, 일시 중지.
         if (_controller.value.isPlaying) {
            _controller.pause();
         } else {
            // 만약 영상 일시 중지 상태였다면, 재생.
            _controller.play();
         }
      });
   },
   // 플레이어 상태에 따라 올바른 아이콘 보여줌.
   child: Icon(
      _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
   ),
)

 

 

 

 

최종 완성 코드

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

void main() => runApp(VideoPlayerApp());

class VideoPlayerApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Video Player Demo',
      home: VideoPlayerScreen(),
    );
  }
}

class VideoPlayerScreen extends StatefulWidget {
  VideoPlayerScreen() : super();

  // createState() : tree의 지정된 위치에서 이 widget의 변경 가능한 상태 생성
  @override
  _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  VideoPlayerController _controller;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    // VideoPlayerController를 저장하기 위한 변수를 생성.
    // VideoPlayerController : asset, file, network 등 영상들을 제어하기 위해 다양한 생성자 제공.
    // _controller = VideoPlayerController.asset('assets/videos/butterfly.mp4'); //file play
    _controller = VideoPlayerController.network(
      'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4', //live play
    );

    // initialize() : 지정된 dataSource 열고 비디오에 대한 metadata load
    // 컨트롤러를 초기화하고 추후 사용하기 위해 Future를 변수에 할당.
    _initializeVideoPlayerFuture = _controller.initialize();

    // 비디오를 반복 재생하기 위해 컨트롤러를 사용.
    _controller.setLooping(true);

    super.initState();
  }

  @override
  void dispose() {
    // 자원을 반환하기 위해 VideoPlayerController dispose.
    _controller.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Butterfly Video'),
      ),
      // FutureBuilder : VideoPlayerController가 초기화 진행하는 동안 로딩 스피너를 보여주기 위함
      body: FutureBuilder(
        future: _initializeVideoPlayerFuture,
        builder: (context, snapshot) {
          // ConnectionState : 비동기 계산에 대한 연결 상태
          if (snapshot.connectionState == ConnectionState.done) {
            // VideoPlayerController 초기화 끝나면, 제공된 데이터 사용하여 VideoPlayer 종횡비 제한.
            return AspectRatio(
              aspectRatio: _controller.value.aspectRatio,
              // 영상 보여주기 위해 VideoPlayer 위젯 사용.
              child: VideoPlayer(_controller),
            );
          } else {
            // 만약 VideoPlayerController가 여전히 초기화 중이라면, 로딩 스피너를 보여줌.
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 재생/일시 중지 기능을 setState에 넣음. 아이콘 변경 위함
          setState(() {
            // 영상 재생 중이라면, 일시 중지.
            if (_controller.value.isPlaying) {
              _controller.pause();
            } else {
              // 만약 영상 일시 중지 상태였다면, 재생.
              _controller.play();
            }
          });
        },
        // 플레이어 상태에 따라 올바른 아이콘 보여줌.
        child: Icon(
          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ), // 이 마지막 콤마는 build 메서드에 자동 서식이 잘 적용될 수 있도록 도와줌.
    );
  }
}

 

 

 

 

 

 

참고 : flutter-ko.dev/docs/cookbook/plugins/play-video

 

영상 재생 및 일시 중지

앱 개발에 있어 영상 재생은 일반적인 작업으로 Flutter에서도 예외는 아닙니다. 영상을재생하기 위해 Flutter는 [`video_player`]({{site.pub-pkg}}/video_player) 플러그인을제공하고 있습니다. `video_player` 플러

flutter-ko.dev

 

 

 

 

 

 

 

320x100

'프로그래밍 > Flutter-Dart' 카테고리의 다른 글

[Flutter] Layout App (2)  (0) 2021.03.17
[Flutter] Layout App (1)  (0) 2021.03.17
[Flutter] Flutter Widget  (0) 2021.03.16
[Flutter] Flutter App (4)  (0) 2021.03.16
[Flutter] Flutter App (3)  (0) 2021.03.16

댓글