首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在android中播放安全可靠的传输?

如何在android中播放安全可靠的传输?
EN

Stack Overflow用户
提问于 2021-10-31 16:27:03
回答 1查看 49关注 0票数 0

我想知道是否可以使用安全可靠的传输协议来播放视频。此类型的视频以srt://开头。我知道VideoView只支持https和另一个我不记得的协议,但不支持srt。

任何尝试用谷歌搜索都会得到关于srt字幕文件的结果,这不是我要找的。

有人知道如何在android上播放srt视频吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-12 07:19:49

如果有人来这里寻找答案,这是我为了让它工作而做的事情。我的方法是用于实况流,但它可以修改为适用于单个文件类型的视频。

我设法实现了一个与实时流SRT一起工作的自定义ExoPlayer DataSource。

Uses srtdroid library

工厂

代码语言:javascript
复制
class SrtLiveStreamDataSourceFactory(
    private val srtUrl: String,
    private val port: Int,
    private val passPhrase: String? = null
) :
    DataSource.Factory {
    override fun createDataSource(): DataSource {
        return SrtLiveStreamDataSource(srtUrl, port, passPhrase)
    }
}

DataSource

代码语言:javascript
复制
const val PAYLOAD_SIZE = 1316


class SrtLiveStreamDataSource(
    private val srtUrl: String,
    private val port: Int,
    private val passPhrase: String?

) :
    BaseDataSource(/*isNetwork*/true) {

    private var socket: Socket? = null
    private val byteQueue: Queue<Byte> = LinkedList()


    override fun open(dataSpec: DataSpec): Long {
        socket = Socket()
        socket?.setSockFlag(SockOpt.TRANSTYPE, Transtype.LIVE)
        socket?.setSockFlag(SockOpt.PAYLOADSIZE, PAYLOAD_SIZE)
        if(passPhrase != null){
            socket?.setSockFlag(SockOpt.PASSPHRASE, passPhrase)
        }
        socket?.connect(srtUrl, port)
        return C.LENGTH_UNSET.toLong()
    }


    /**
     * Receives from SRT socket and feeds into a queue. Depending on the length requested
     * from exoplayer, that amount of bytes is polled from queue and onto the buffer with the given offset.
     *
     * You cannot directly receive at the given length from the socket, because SRT uses a
     * predetermined payload size that cannot be dynamic
     */
    override fun read(buffer: ByteArray, offset: Int, length: Int): Int {
        if (length == 0) {
            return 0
        }
        var bytesReceived = 0
        if (socket != null) {
            val received = socket!!.recv(PAYLOAD_SIZE)
            for (byte in received.second /*received byte array*/) {
                byteQueue.offer(byte)
            }
            repeat(length) { index ->
                val byte = byteQueue.poll()
                if (byte != null) {
                    buffer[index + offset] = byte
                    bytesReceived++
                }
            }
            return bytesReceived
        }
        throw IOException("Couldn't read bytes at offset: $offset")
    }

    override fun getUri(): Uri? {
        return Uri.parse("srt://$srtUrl:$port")
    }

    override fun close() {
        socket?.close()
        socket = null
    }
}

简单用法

代码语言:javascript
复制
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)


        val url = SRT_URL_HERE (exclude srt://)
        val port = PORT_HERE

        val source = ProgressiveMediaSource.Factory(
            SrtLiveStreamDataSourceFactory(
                url,
                port,
            ),
        ).createMediaSource(MediaItem.fromUri(Uri.EMPTY))


        val player = ExoPlayer.Builder(this)
            .build()
        player.setMediaSource(source)
        binding.playerView.player = player


        player.prepare()
        player.play()
        player.playWhenReady = true

    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69788480

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档