安卓---视频模块需求(1)-android M3U8格式视频解析

 最近做需求,视频看房,上传的视频,通过发送到亚马逊服务器,分片上传,上传成功后,在房屋详情页得到的url是一个M3U8格式的url,这个时候是需要自己去解析M3U8,然后获取到视频列表,以及视频清晰度内容的。

下面来介绍下M3U8

m3u8 文件格式详解 - 简书

这个网址的内容能解释 M3U8

这是后台返回的URL(含有M3U8后缀的url),可以看到有 720 480 360 格式

这是根据对应的M3U8打开后的文件内容

最后效果图

直接上代码:

class MainActivity : AppCompatActivity() {

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

        ParserThread().execute()
    }

    private inner class ParserThread : AsyncTask<Void, Void, Map<String, Int>>() {
        internal lateinit var url: URL

        override fun doInBackground(vararg voids: Void): Map<String, Int>? {
            try {
                this.url = URL("https://video.591.com.tw/debug/target/house/hls/2021-07-14/130/master.m3u8")
                val urlConnection = this.url.openConnection() as HttpURLConnection
                urlConnection.connectTimeout = 60000
                urlConnection.readTimeout = 30000
                urlConnection.requestMethod = "GET"

                urlConnection.connect()

                return parseHLSMetadata(urlConnection.inputStream, this.url)

            } catch (e: IOException) {
                e.printStackTrace()
            }

            return null
        }

        override fun onPostExecute(aVoid: Map<String, Int>?) {
            super.onPostExecute(aVoid)
            if (aVoid == null) return
            Log.d("Khaleel", "aVoid : " + aVoid)
        }
    }

    private fun parseHLSMetadata(i: InputStream, url: URL): HashMap<String, Int>? {

        try {
            val r = BufferedReader(InputStreamReader(i, "UTF-8"))
            val segmentsMap: HashMap<String, Int>? = null
            val pattern = Pattern.compile("^#EXT-X-STREAM-INF:.*BANDWIDTH=(\\d+).*RESOLUTION=([\\dx]+).*")
            do {
                val line: String? = r.readLine() ?: break
                Log.d("M3U8Parser", "BufferedReader : " + line)
                val match = pattern.matcher(line)
                if (match.matches()) {
                    Log.d("M3U8Parser", "Output 1: " + match.group())
                    Log.d("M3U8Parser", "Output 2: " + match.group(1))
                    Log.d("M3U8Parser", "Output 3: " + match.group(2).split("x".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()[0])
                    val renditionUrl = r.readLine()
                    Log.d("M3U8Parser", "Output 4: " + renditionUrl)
                    Log.d("M3U8Parser", "Output 5: " + url.host + "--" + url.protocol)
                    var rendition: URL
                    rendition = try {
                        URL(renditionUrl)
                    } catch (e: MalformedURLException) {
                        URL(url.protocol + "://" + url.host + "/" + renditionUrl)
                    }
                    Log.d("M3U8Parser", "Output 6:" + rendition.toString())
                }
            } while (line != null)
            r.close()
            return segmentsMap
        } catch (e: IOException) {
            e.printStackTrace()
        }

        return null
    }
}

おすすめ

転載: blog.csdn.net/yangbin0513/article/details/119380838