본문 바로가기

코딩/안드로이드

안드로이드 Picture In Picture (PIP)

깃 헙 주소 : https://github.com/5seunghoon/PipExample 

 

PIP기능은 아래와 같다

 

 

이렇게 재생되던 동영상을, 홈키같은걸 눌리게 되면

 

이렇게 작은화면으로 전환되고, 다른 앱 위에서 동영상이 계속 재생될 수 있는 기능이다.

 

유튜브나 네이버TV등에서 자주 볼 수 있는 기능이다.

 

이를 간단하게 구현해보자.

 

먼저 깃헙 주소는 게시글의 최상단에 미리 적어놓았다.

 

 

 

1. 매니패스트의 액티비티 부분을 다음과 같이 수정하자 

<activity android:name=".MainActivity"
                  android:resizeableActivity="true"
                  android:supportsPictureInPicture="true"
                  android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <action android:name="android.intent.action.VIEW"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

보면, android:resizeableActivity과 supportPictureInPicture이 설정되어 있는 것을 알 수 있다.

 

 

2. 액티비티 xml 수정

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">
    <VideoView
            android:layout_width="match_parent"
            android:layout_height="match_parent" android:id="@+id/main_video_view" />
    <ScrollView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:orientation="vertical">
        <Button
                android:text="GO TO PIP!"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" android:id="@+id/main_go_to_pip"
                android:backgroundTint="@android:color/holo_orange_light" />
    </ScrollView>
</LinearLayout>

먼저 VideoView를 리니어 레이아웃의 최상단에 두고, 스크롤뷰를 그 밑에 둔 다음 그 스크롤뷰에 이것저것 넣으면 된다.

 

주의할 점은, 이 예제에서는 버튼 하나만 있으면 되서 그냥 스크롤뷰에 버튼 때려박았는데,

비디오 밑에 컴포넌트들을 여러개 넣고 싶으면 스크롤뷰가 리니어 레이아웃을 반드시 하나 포함하게 하고,

그 리니어 레이아웃에 컴포넌트를 여러개 넣으면 된다.

 

 

3. 액티비티의 수정

class MainActivity : AppCompatActivity() {

    private val mPipBuilder = PictureInPictureParams.Builder()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        main_video_view?.run {
            setOnCompletionListener { it.start() }
            setVideoURI(Uri.parse("android.resource://$packageName/${R.raw.sample}"))
            start()
        }

        main_go_to_pip?.setOnClickListener {
            mPipBuilder.setAspectRatio(Rational(main_video_view.width, main_video_view.height))
            enterPictureInPictureMode(mPipBuilder.build())
        }
    }
}

 

그 후, 이렇게 비디오를 재생할 비디오 뷰와 pip로 전환하는 기능을 수행하는 버튼을 설정해준다.

 

setOnCompletionListener는, 영상이 끝나면 영상을 재시작하게 해서 무한 반복하게 만드는 코드고,

setVideoURI는, Uri.parse를 통해 res폴더에 있는 비디오를 비디오 뷰에 set시켜주는 코드이다.

 

아, 지금 예제에는 res폴더에 raw디렉토리에 비디오가 하나 있는데, 용량이 커서 깃에는 ignore시켜두었다.

 

여러분들이 원하는 아무 비디오 파일을 res/raw에 하나 넣으면 될거 같다.

 

아래와 같이.

 

 

또한, pip로 전환하는 버튼은 간단하게 두가지 함수를 실행한다.

먼저 PictureInPicture.Builder 클래스에 AspectRatio(화면비율)를 할당해준다.

그 후 enterPictureInPicture함수에 해당 빌더의 빌드 결과물을 인자로 넘겨주고 실행함으로써 

액티비티를 PIP로 전환한다.

 

 

5. 스타일의 수정

 

이때, 액티비티에 만약 ActionBar가 있으면 PIP로 바뀐 작은 액티비티에도 액션바가 보이게 되니 

    <style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

이러한 앱 테마를 하나 만들고 액티비티에 이 테마를 설정해주면 된다.

 

 

 

 

끝이다.

 

아주 간단하게 PIP를 구현할 수 있는데, 

 

만약 상용하고 있는 앱들 처럼 PIP의 비디오 뷰에 재생, 일시정지 등의 버튼을 달고 싶으면

 

Surface View를 상속하는 Custom Video View를 만들어서 그걸 이용하면 될 거같다.

 

커스텀 비디오 뷰를 이용한 PIP와 관련된 소스코드를 함께 소개하고 글을 끝마치겠다. 

https://github.com/googlesamples/android-PictureInPicture