ExoPlayer рдореЗрдВ WebVTT рдЙрдкрд╢реАрд░реНрд╖рдХ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдФрд░ рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдВ

рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░ред

рдХреБрдЫ рджрд┐рдиреЛрдВ рдкрд╣рд▓реЗ HLS рд╕реНрдЯреНрд░реАрдо рдореЗрдВ WebVTT рд╕рдмрдЯрд╛рдЗрдЯ рдХреЛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдХрд╛рд░реНрдп рдерд╛ред
рд╣рдо рдПрдХреНрд╕реЛрдкреНрд▓реЗрдпрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡реАрдбрд┐рдпреЛ рдЦреЗрд▓рддреЗ рд╣реИрдВ, рдФрд░ рдкрд╣рд▓реЗ рдРрд╕рд╛ рд▓рдЧрддрд╛ рдерд╛ рдХрд┐ Google рдФрд░ рдХрдВрдкрдиреА рдХреЛ "рд▓рд┐рдпрд╛ рдФрд░ рдХрд┐рдпрд╛" рдмреЙрдХреНрд╕ рд╕реЗ рдПрдХ рд╕рдорд╛рдзрд╛рди рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдерд╛ред рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рдЕрдкреЗрдХреНрд╖рд╛ рдХреЗ рдЕрдиреБрд░реВрдк рдирд╣реАрдВ рдереА :)

Googling рдФрд░ Habring рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рдирд┐рдХрд▓рд╛ рдФрд░ рдпрд╣ рд╕рднреА рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдбреЗрдореЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди ExoPlayer рдХреЛ рдЪреБрдирдиреЗ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рдЖрдпрд╛ ред

рдЪреВрдВрдХрд┐ рдЪреВрдВрдХрд┐ рд▓реЗрдЦ рдПрдЪрдПрд▓рдПрд╕ рдХреА рд╕рдВрд░рдЪрдирд╛ рдФрд░ рдПрдХреНрд╕реЛрдкреНрд▓реЗрдпрд░ рдореЗрдВ рдХреБрдЫ рдЕрдиреБрднрд╡ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдкрд░рд┐рдЪрд┐рддрддрд╛ рдорд╛рдирддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдмрд┐рдВрджреБ рдкрд░ рд╕рд╣реА рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред

рдпрд╣ рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рд╕реНрдЯреНрд░реАрдо (рд╡реАрдбрд┐рдпреЛ, рдСрдбрд┐рдпреЛ, рдЙрдкрд╢реАрд░реНрд╖рдХ) рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджрд╕реНрддрд╛рд╡реЗрдЬ рд╣рдореЗрдВ рдмрддрд╛рддрд╛ рд╣реИ ред рдФрд░ рд╡рд╣ рд╣рдореЗрдВ рд▓рдЧрднрдЧ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрддрд╛рддреА рд╣реИ - DefaultTrackSelector рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░реЗрдВ рдФрд░ рдЙрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдпрд╣ рдареАрдХ рд╣реИ, :)

рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдкрдЯрд░рд┐рдпреЛрдВ (CEA-608, WebVtt) рдХреЗ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдЯреНрд░реИрдХ рдХреА рддрд░рд╣ рд╕рднреА рдЙрдкрд╢реАрд░реНрд╖рдХ DefaultTrackSelector рдХреЗ рдЕрдВрджрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ рдФрд░ рдЖрдкрдХреЛ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рдм рдХреБрдЫ рд╕рдореВрд╣реЛрдВ рдФрд░ рдЙрдкрд╕рдореВрд╣реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИ, рдФрд░ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ, рдЖрдВрддрд░рд┐рдХ рд╕рдВрд░рдЪрдирд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреА рд╣реИ:


рдЪрд▓рд┐рдП рдЕрдм WebVTT рдХреЗ рдЙрдкрд╢реАрд░реНрд╖рдХ рдкрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рд░реЗрдВрдбрд░рд░ рдХреЗ рдЕрдВрджрд░ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП "3" (C.TRACK_TYPE_TEXT - Exo рдореЗрдВ рд╕реНрдерд┐рд░):

fun getVttSubtitles(): List<String> {
        val tracks = mutableListOf<String>()
        //  MappedTrackInfo
        defaultTrackSelector.currentMappedTrackInfo?.let { mappedTrackInfo ->
            val renderCount = mappedTrackInfo.rendererCount
            for (renderIndex in 0 until renderCount) {
                //    renderer'    TEXT
                val renderType = mappedTrackInfo.getRendererType(renderIndex)
                if (renderType == C.TRACK_TYPE_TEXT) {
                    val trackGroupArray = mappedTrackInfo.getTrackGroups(renderIndex)
                    //    
                    for (trackGroupArrayIndex in 0 until trackGroupArray.length) {
                        val trackGroup = trackGroupArray[trackGroupArrayIndex]
                        for (trackGroupIndex in 0 until trackGroup.length) {
                            //       TEXT_VTT
                            val format = trackGroup.getFormat(trackGroupIndex)
                            if (format.sampleMimeType == MimeTypes.TEXT_VTT) {
                                tracks += format.language.orEmpty()
                            }
                        }
                    }
                }
            }
        }

        return tracks
    }

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХреБрдЫ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗ рд╕реЗ рдкреБрдирд░рд╛рд╡реГрддрд┐ рдФрд░ рдЦреЛрдЬ рдкреНрд░рджрд╛рди рдирд╣реАрдВ рдХреА рдЧрдИ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдкреЗрди рдХреЗ рд╕рд╛рде рд╕рднреА рдЫреЛрд░реЛрдВ рдХреЛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рди рдХреЗрд╡рд▓ рд╕реВрдЪреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдмрд▓реНрдХрд┐ рдЪрдпрдирд┐рдд рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рднреА рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ (рдЬреЛ рд╣рдо рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЪреБрдиреЗрдВрдЧреЗ)ред рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ, рдЖрдк DefaultTrackSelector рд╕реЗ рдЪрдпрдирд┐рдд рдЯреНрд░реИрдХ рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдк рд╕реНрд╡рдпрдВ ExoPlayer рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рд▓рдЧрднрдЧ рд╕рдорд╛рди рд╣реИ, рд╣рдо рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рд╣рдо рд░реЗрдВрдбрд░рд░реНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдорд╛рд░реНрдЧ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ:

fun getSelectedVttSubtitles(): List<String> {
        val selectedLangs = mutableListOf<String>()
        val currentTrackSelections = exoPlayer.currentTrackSelections
        for (selectionIndex in 0 until currentTrackSelections.length) {
            val trackSelection = currentTrackSelections[selectionIndex]
            if (trackSelection != null) {
                //     
                val length = trackSelection.length()
                for (trackIndex in 0 until length) {
                    //      
                    val format = trackSelection.getFormat(trackIndex)
                    if (format.sampleMimeType == MimeTypes.TEXT_VTT) {
                        selectedLangs += format.language.orEmpty()
                    }
                }
            }
        }

        return selectedLangs
    }

рдЦреИрд░, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕реВрдЪреА рдФрд░ рдЪрдпрдирд┐рдд рд▓реЛрдЧреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рд╣реИред UI рдкрд░ рд╕рдВрдпреЛрдЬрди рдФрд░ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдирд╛ рдЗрд╕ рд▓реЗрдЦ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдирд╣реАрдВ рд╣реИред рдмрд╣реБрдд рддрд░реАрдХреЗ рд╣реИрдВред рд╣рдореЗрдВ рд╕рд┐рд░реНрдл рдЯреНрд░реИрдХ рд╕реЗрдЯ рдХрд░рдирд╛ рд╕реАрдЦрдирд╛ рд╣реЛрдЧрд╛ред

рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ рдорд╛рдереЗ рдХреЗ рддрд░реАрдХреЗ рд╕реЗ рдХрд░реЗрдВрдЧреЗ, рддрд╛рдХрд┐ рд╕рднреА рдЪрдХреНрд░ рдФрд░ рд╕реВрдЪрдХрд╛рдВрдХ рд╕реНрдкрд╖реНрдЯ рд╣реЛрдВред

рдЕрдкрдиреЗ рднрд╛рд╖рд╛ рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рдЯреНрд░реИрдХ рдХреА рд╕реНрдерд╛рдкрдирд╛ ("рдЖрд░рдпреВ", "рдПрди", ...):

fun selectTrackByIsoCodeAndType(langCode: String) {
        defaultTrackSelector.currentMappedTrackInfo?.let { mappedTrackInfo ->
            //         
            val renderCount = mappedTrackInfo.rendererCount
            for (renderIndex in 0 until renderCount) {
                //    renderer'    TEXT
                val renderType = mappedTrackInfo.getRendererType(renderIndex)
                if (renderType == C.TRACK_TYPE_TEXT) {
                    val trackGroupArray = mappedTrackInfo.getTrackGroups(renderIndex)
                    //    
                    for (trackGroupArrayIndex in 0 until trackGroupArray.length) {
                        val trackGroup = trackGroupArray[trackGroupArrayIndex]
                        for (trackGroupIndex in 0 until trackGroup.length) {
                            val format = trackGroup.getFormat(trackGroupIndex)
                            //       
                            if (format.sampleMimeType == MimeTypes.TEXT_VTT
                                && format.language == langCode
                            ) {
                                //    
                                val currentParams = defaultTrackSelector.buildUponParameters()
                                //   ( )
                                //  
                                currentParams.clearSelectionOverride(
                                    renderIndex, trackGroupArray
                                )

                                // ,    
                                //       

                                //       
                                val override = DefaultTrackSelector.SelectionOverride(
                                    trackGroupArrayIndex, trackGroupIndex
                                )

                                //     
                                currentParams.setSelectionOverride(
                                    renderIndex,
                                    trackGroupArray,
                                    override
                                )

                                //     
                                defaultTrackSelector.setParameters(currentParams)

                                return
                            }
                        }
                    }
                }
            }
        }
    }

рдирд┐рд╖реНрдХрд░реНрд╖


рд╣рдордиреЗ ExoPlayer рдореЗрдВ WebVTT рдЙрдкрд╢реАрд░реНрд╖рдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рдХрд╡рд░ рдХреА рд╣реИрдВред
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрдХ рд╣реА рд╡рд┐рдзрд┐ рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдиреНрдп рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдмрдЯрд╛рдЗрдЯрд▓реНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреА рд╣реИ - рдпрд╣ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рд╛рде рддрд░реАрдХреЛрдВ рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред рдЙрд╕реА рддрд░рд╣, рдСрдбрд┐рдпреЛ рдЯреНрд░реИрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдмреЗрд╢рдХ, рдЗрд╕ рд░реВрдк рдореЗрдВ рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХрд╛рдлреА рдХрдард┐рди рд╣реИ рдФрд░ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд░реВрдк рдореЗрдВ рд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдзрдиреНрдпрд╡рд╛рджред

All Articles