我想知道是否可以使用安全可靠的传输协议来播放视频。此类型的视频以srt://开头。我知道VideoView只支持https和另一个我不记得的协议,但不支持srt。
任何尝试用谷歌搜索都会得到关于srt字幕文件的结果,这不是我要找的。
有人知道如何在android上播放srt视频吗?
发布于 2021-11-12 07:19:49
如果有人来这里寻找答案,这是我为了让它工作而做的事情。我的方法是用于实况流,但它可以修改为适用于单个文件类型的视频。
我设法实现了一个与实时流SRT一起工作的自定义ExoPlayer DataSource。
工厂
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
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
}
}简单用法
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
}
}https://stackoverflow.com/questions/69788480
复制相似问题