ShopLivePreview 사용하기

    ShopLivePreview 사용하기


    기사 요약

    Shoplive SDK에서 제공하는  ShopLivePreview를 이용하여 기본 In App 미리보기를 직접 구현할 수 있습니다.

    // If only one of width or height is written, it is flexible.
    <cloud.shoplive.sdk.ShopLivePreview
        android:id="@+id/preview"
        android:layout_width="width"
        android:layout_height="height">
        <com.example.someChildView
            android:layout_width="width"
            android:layout_height="height"/>
    </cloud.shoplive.sdk.ShopLivePreview>

    preview.start(“{accessKey}”, “{campaignKey}”)
    preview.setOnClickListener {     
        // Preview transition animation      
        ShopLive.setPreviewTransitionAnimation(requireActivity(), binding.preview)
        ShopLive.play(requireActivity(), campaignKey)
        preview.release()
    } 
    
    // For lifecycle observing preview
    preview.setLifecycleObserver(this.viewLifecycleOwner)

    미리보기 소리 재생하기

    미리보기는 기본값이 음소거입니다(isMuted = true). 재생 시작부터 소리를 내려면 음소거를 해제하세요.

    팝업 미리보기 — ShopLive.showPreviewPopup

    ShopLive.showPreviewPopup(
        activity,
        ShopLivePreviewData(campaignKey).apply {
            // 기본값은 true(음소거)입니다. 처음부터 소리를 내려면 false 로 설정하세요.
            isMuted = false
            // 사용자가 볼륨 키로 음소거를 조절하게 하려면 함께 설정하세요. 기본값 false.
            isEnabledVolumeKey = true
        }
    )

    인라인 미리보기 — 레이아웃에 ShopLivePreview 를 직접 배치한 경우

    preview.setMuted(false)
    preview.setEnabledVolumeKey(true) // 선택

    음소거를 해제해도 방송 영상 자체에 오디오가 없으면 소리가 나지 않습니다. 소리가 들리지 않으면 먼저 해당 방송의 오디오 유무를 확인해 주세요.


    RecyclerView 사용 시 참고사항

    • ViewHolder가 detached 될 때는 반드시 preview.release()를 호출하세요.

    • ViewHolder가 attached 될 때는 preview.start()를 호출하세요.

    RecyclerView예제

    class TestPreviewListActivity : AppCompatActivity() {
        companion object {
            private const val EXTRA_CAMPAIGN_KEY = "extra_campaign_key"
            private const val EXTRA_IS_MUTED = "extra_is_muted"
    
            fun intent(context: Context, campaignKey: String, isMuted: Boolean): Intent {
                return Intent(context, TestPreviewListActivity::class.java)
                    .putExtra(EXTRA_CAMPAIGN_KEY, campaignKey)
                    .putExtra(EXTRA_IS_MUTED, isMuted)
            }
        }
    
        private val binding: ActivityTestPreviewListBinding by lazy {
            ActivityTestPreviewListBinding.inflate(layoutInflater)
        }
    
        private val campaignKey: String by lazy {
            intent.getStringExtra(EXTRA_CAMPAIGN_KEY) ?: throw IllegalArgumentException()
        }
    
        private val isMuted: Boolean by lazy {
            intent.getBooleanExtra(EXTRA_IS_MUTED, true)
        }
    
        private val releaseLiveData = ShopLiveSingleLiveData<Boolean?>(null)
    
        private val adapter by lazy {
            PreviewListAdapter(this, releaseLiveData, isMuted)
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(binding.root)
    
            binding.testPreviewRecyclerview.layoutManager =
                LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
            binding.testPreviewRecyclerview.adapter = adapter
            adapter.submitList(
                listOf(
                    campaignKey,
                    campaignKey,
                    campaignKey
                )
            )
        }
    
        override fun onDetachedFromWindow() {
            super.onDetachedFromWindow()
            releaseLiveData.value = true
        }
    }
    
    private class PreviewListAdapter(
        private val owner: LifecycleOwner,
        private val releaseLiveData: LiveData<Boolean?>,
        private val isMuted: Boolean,
    ) :
        ListAdapter<String, PreviewListAdapter.ViewHolder>(object : DiffUtil.ItemCallback<String>() {
            override fun areContentsTheSame(oldItem: String, newItem: String) =
                true
    
            override fun areItemsTheSame(oldItem: String, newItem: String) =
                oldItem == newItem
        }) {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            return ViewHolder(
                LayoutInflater.from(parent.context)
                    .inflate(R.layout.holder_test_preview_list, parent, false)
            )
        }
    
        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            holder.onBind(getItem(position))
        }
    
        override fun onViewAttachedToWindow(holder: ViewHolder) {
            super.onViewAttachedToWindow(holder)
            holder.onViewAttachedToWindow()
        }
    
        override fun onViewDetachedFromWindow(holder: ViewHolder) {
            super.onViewDetachedFromWindow(holder)
            holder.onViewDetachedFromWindow()
        }
    
        inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
            private val releaseObserver = Observer<Boolean?> {
                it ?: return@Observer
                preview.release()
            }
    
            private val preview: ShopLivePreview = view.findViewById(R.id.testPreview)
    
            fun onBind(campaignKey: String) {
                preview.initializePlayer()
                preview.setLifecycleObserver(owner)
                preview.apply {
                    this.campaignKey = campaignKey
                    this.setMuted(isMuted)
                    if (Options.isCenterCrop()) {
                        this.setResizeMode(ShopLiveResizeMode.CENTER_CROP)
                    } else {
                        this.setResizeMode(ShopLiveResizeMode.FIT)
                    }
                    setPostCampaignImageVisible(Options.isShowPostCampaignImagePreview())
                }
            }
    
            fun onViewAttachedToWindow() {
                preview.start()
                releaseLiveData.observeForever(releaseObserver)
            }
    
            fun onViewDetachedFromWindow() {
                preview.release()
                releaseLiveData.removeObserver(releaseObserver)
            }
        }
    }