Android (안드로이드)

[Android] libvlc - RTSP 스트리밍 연결

Oscar:) 2024. 11. 29. 19:00
728x90

 

 

지난 ExoPlayer 포스팅에 이어, 이번엔 libvlc 라이브러리를 가지고 왔다.

 

해당 라이브러리는 VLC에서 제공하는 외부 라이브러리다.

 

 

 

 

✅ VLC (Video LAN Clients)

 

VideoLan Project에서 개발하는 오픈소스 미디어 재생기이며,

자체 코덱 내장 및 높은 호환성으로 현존하는 미디어 플레이어 중 최고라 볼 수 있다.

 

 

libvlc는 안드로이드 뿐 아니라, 다양한 플러그인을 지원하기에

우리가 사용해볼 라이브러리는 libvlc-Android 버전이라 볼 수 있다.

 

 

라이브러리 경로는 다음과 같다 ↓

 

Files · master · VideoLAN / VLC-Android · GitLab

VLC for Android, Android TV and ChromeOS

code.videolan.org

 

 

 

친절히도 VLC에서 제공하는 안드로이드 전용 샘플 코드도 존재한다 ↓

 

VideoLAN / LibVLC Android samples · GitLab

VideoLAN code repositories

code.videolan.org

 

 

 

위 샘플 코드를 기반으로 예제를 진행해보겠다.

 

 

 


 

 

 

✅ Manifest 권한 추가

 

AndroidManifest.xml

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

 

이전 포스팅과 마찬가지로,  네트워크 스트리밍을 진행할 것이기에 인터넷 권한을 추가해준다.

 

 

 

 

 

✅ 의존성 설정

 

build.gradle.kts (Module:app)

implementation("org.videolan.android:libvlc-all:3.5.1")

 

최신 버전은 위 라이브러리 링크에서 확인바란다.

 

 

 

 

 

✅ 레이아웃 설정

 

activity_main.xml

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        >

        <org.videolan.libvlc.util.VLCVideoLayout
            android:id="@+id/videolayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />

    </FrameLayout>

 

VLCVideoLayout의 height 값을 수동으로 입력해도 높이가 변하지 않는다.

그렇기에 위 처럼 FrameLayout으로 높이를 지정하고 래핑해줄 수 있다.

 

 

 

 

 

✅ RTSP 스트리밍

 

스트리밍에 필요한 코드는 다음과 같다.

 

MainActivity.kt

private fun playerInit() {
    
	// 네트워크 스트림 주소를 Uri 형식으로 초기화
	val uri = "rtsp://210.99.70.120:1935/live/cctv048.stream".toUri()
        
	// libvlc 및 MediaPlayer 초기화
	val libVlc = LibVLC(this)
	val mediaPlayer = MediaPlayer(libVlc)
        
	// MediaPlayer와 레이아웃에 선언한 videolayout을 연결
	mediaPlayer.attachViews(bind.videolayout, null, false, false)
        
	// libvlc 객체와 스트림 주소로 Media 객체 초기화 후 MediaPlayer에 연결
	val media = Media(libVlc, uri)
	mediaPlayer.media = media
        
	// Media 릴리즈 후 MediaPlayer 재생
	media.release()
	mediaPlayer.play()
        
	// 미디어 플레이어에서 발생하는 이벤트 리스너
	mediaPlayer.setEventListener {
		// MediaPlayer.Event 객체가 던져짐
	}
        
}


override fun onCreate() {
	...
	playerInit()
}

 

코드 한 줄마다 주석을 달아놨으니 확인바란다.

 

간단히 추가 설명이 필요할 것 같은 부분은 MediaPlayer.attachViews() 함수인데,

파라미터를 4개나 받는다.

 

● attachViews(VLCVideoLayout, DisplayManager, Subtitles, TextureView)

- VLCVideoLayout : 레이아웃 파일에 선언한 VideoLayout을 연결해주면 된다.

- DisplayManager : 렌더링 전환용 변수 옵션을 추가할 수 있다.

- Subtitles : 자막 활성/비활성 값을 Boolean으로 작성한다.

- TextureView : TextureView = true / SurfaceView = false

 

 

 

 

MediaPlayer.setEventListener에서는 스트리밍 시작 ~ 종료까지의 다양한 이벤트를 수신할 수 있다.

 

예를 들어 다음과 같이 Event.buffering 로그를 찍어보면

mediaPlayer.setEventListener {
	Log.d(TAG, "buffering: ${it.buffering.toInt()}")
}

 

버퍼링 수치를 확인할 수 있다.

 

 

위 스크린샷을 보면 알겠지만, 버퍼링이 100이 되어 영상이 출력되면 다시 0으로 돌아간다.

이 버퍼링 수치를 사용자에게 보여주는 기능을 간단히 만들어본다.

 

var isLoaded = false
mediaPlayer.setEventListener {
    if (!isLoaded) {
    	when (it.buffering.toInt()) {
            0 -> bind.progressbar.visibility = View.VISIBLE
            100 -> {
            	bind.textview.visibility = View.GONE
                isLoaded = true
            }
            else -> {
            	bind.textview.text = "${it.buffering.toInt()}%"
                bind.progressbar.visibility = View.GONE
                bind.textview.visibility = View.VISIBLE
            }
        }
    }
}

 

VideoLayout 중앙에 버퍼링 표시할 TextView를 하나 만들어놓고,

 

버퍼링 0 → 프로그래스바 표시

버퍼링 1~99 → 버퍼링 수치 표시

버퍼링 100 → 영상만 출력

 

위와 같이 작성했다.

추후에도 리스너에 버퍼링 0이 계속 호출되므로, Boolean 변수로 체크한다.

 

 

 

 

 

✅ 결과

 

● 스트리밍 연결 중

 

버퍼링이 0을 벗어날 때까지 프로그래스바가 표시된다.

 

 

 

 

 

● 스트리밍 연결 후 버퍼링

 

프로그래스바가 사라지며 영상 중앙에 버퍼링 숫자%가 올라가고 있는 모습이다.

 

스트림 연결 상태에 따라서 검정 화면에 버퍼링 숫자%가 표시될 때도 있고,

위 처럼 영상 썸네일이 로드된 후 버퍼링 숫자%가 표시될 때도 있다.

 

 

 

 

 

● 스트리밍 연결 성공 후

 

영상이 재생되는 모습이다.

 

 

 

 

 


 

 

 

 

VLC 플레이어도 명성에 걸맞게 안정적으로 RTSP 스트리밍을 지원한다.

 

 

 

 

 

728x90