video_player http, mjpeg 권한

Flutter

목록 보기
12/12

Video_player

  • pubspec.yaml 에 라이브러리 추가
VideoPlayerController.networkUrl(Uri.parse('http://172.30.1.60:8080/video'))

안드로이드에서 http 를 통해 동영상 받아오는 코드

안드로이드
android/app/src/main/AndroidManifest.xml
경로에

<uses-permission android:name="android.permission.INTERNET" />
<!-- 네트워크 상태 확인 권한 (선택 사항) -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

권한 추가.

또 기본적으로 안드로이드는 https 와 통신하도록 설정되어있으므로 http 를 받아오는 것이 불가능하지만, 이걸 가능하도록 해주는 설정 추가해야한다.

<application
        android:networkSecurityConfig="@xml/network_security_config"
    	android:usesCleartextTraffic="true">

이 두 줄의 권한을 추가해준다.
추가로
android/app/src/main/res
경로에 xml 폴더를 추가한 뒤 특정 도메인에 대한 접근 허용 파일을 추가해야 한다.

파일 이름

  • network_security_config.xml

허용을 추가할 도메인을 파일에 작성해줌

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
	<domain-config cleartextTrafficPermitted="true">
    	<domain includeSubdomains="true">172.30.1.60</domain>
	</domain-config>
</network-security-config>

이러면 해당 도메인에 대한 http 접근이 허용된다.

기본적으로 video player 의

ExoPlayer 가 처리할 수 있는 것들은
MP4, HLS, DASH 파일이 있음.

이 것을 확인하기 위해 http 가 제공하는 도메인의 형식을 확인 해야 한다.

도메인의 형식을 확인하려면 http 의 헤더안의 content-type 을 확인해보면 되는데,

Future<void> getStreamInfo() async {
  final response = await http.head(Uri.parse('http://172.30.1.60:8080/video'));
  print('Content-Type: ${response.headers['content-type']}');
}

이 코드를 통해 확인할 수 있다.

응답 헤더에는 Content-Type이 포함되어 있으며, 이를 통해 스트림의 MIME 유형을 알 수 있다.

Content-Type

  • video/mp4,
  • video/x-flv,
  • application/vnd.apple.mpegurl

이런식으로 되어있어야 받기가 가능.

// / Stateful widget to fetch and then display video content.
class VideoApp extends StatefulWidget {
  const VideoApp({super.key});

  @override
  _VideoAppState createState() => _VideoAppState();
}

class _VideoAppState extends State<VideoApp> {
  late VideoPlayerController _controller;

  Future<void> getStreamInfo() async {
    final response = await http.head(Uri.parse('http://172.30.1.60:8080/video'));
    print('Content-Type: ${response.headers['content-type']}');
  }
  @override
  void initState() {
    super.initState();
    getStreamInfo();
    _controller = VideoPlayerController.networkUrl(
        Uri.parse('http://172.30.1.60:8080/video'))
      ..initialize().then((_) {
        _controller.setLooping(true);
        _controller.play();
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        setState(() {});
      });

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
          child: _controller.value.isInitialized
              ? AspectRatio(
                  aspectRatio: _controller.value.aspectRatio,
                  child: VideoPlayer(_controller),
                )
              : Container(),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              _controller.value.isPlaying
                  ? _controller.pause()
                  : _controller.play();
            });
          },
          child: Icon(
            _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
          ),
        ),
      );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

사용 예시

flutter_Mjpeg

Content-Type: multipart/x-mixed-replace

을 스트리밍 처리할 수 있는 라이브러리.

dependencies:
  flutter:
    sdk: flutter
  flutter_mjpeg: ^2.0.4

최신 버전이 2.0.4
이거 사용하려면 http 최신버전을 사용하지 못하는 듯 하다.

http: ^0.13.6

글쓰는 날짜 기준
1.0.0 이상을 사용하지 못하는 듯. 충돌이 발생함

class MjpegStreamScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('MJPEG Stream'),
      ),
      body: Center(
        child: Mjpeg(
          stream: 'http://172.23.248.9:8080/video',
          isLive: true,
        ),
      ),
    );
  }
}

간단하게 사용 가능.

권한도 필요 없는 듯 하다

0개의 댓글