Reputation: 1
I want to play a HEVC (h.265) streaming video via WebSocket.
I created a custom InputStream to construct the VLCMedia object but the player does not work, only got a black view. Is there a different way to initialize the media object or stream the video properly using MobileVLCKit? I'm open to any alternative solutions for streaming the video.
import UIKit
import Starscream
import MobileVLCKit
import Foundation
class WebSocketInputStream: InputStream {
private var buffer: Data = Data() // Buffer to hold incoming WebSocket data
private let bufferLock = NSLock()
private var streamOpen = false
// MARK: - Append WebSocket data to the buffer
func append(_ data: Data) {
bufferLock.lock()
buffer.append(data)
bufferLock.unlock()
}
// MARK: - InputStream methods
override var hasBytesAvailable: Bool {
// There are bytes available if the buffer is not empty
bufferLock.lock()
let available = !buffer.isEmpty
bufferLock.unlock()
return available
}
// Reads up to the specified max length into the provided buffer
override func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength len: Int) -> Int {
bufferLock.lock()
let readLength = min(len, self.buffer.count)
if readLength > 0 {
self.buffer.copyBytes(to: buffer, count: readLength)
self.buffer.removeFirst(readLength)
}
bufferLock.unlock()
return readLength
}
// Open the stream
override func open() {
streamOpen = true
}
// Close the stream
override func close() {
streamOpen = false
bufferLock.lock()
buffer.removeAll()
bufferLock.unlock()
}
// MARK: - Implement stream properties required by InputStream
override var streamStatus: Stream.Status {
return streamOpen ? .open : .closed
}
override var streamError: Error? {
return nil // No specific errors for this simple implementation
}
// You can override other methods as needed depending on your requirements.
}
class VideoViewController: UIViewController {
var socket: WebSocket!
var mediaPlayer: VLCMediaPlayer!
var webSocketStream: WebSocketInputStream!
override func viewDidLoad() {
super.viewDidLoad()
// Setup the WebSocket connection
setupWebSocket()
// Initialize the VLC media player
mediaPlayer = VLCMediaPlayer()
let logger = VLCConsoleLogger()
logger.level = .debug
logger.formatter.contextFlags = .levelContextModule
mediaPlayer.libraryInstance.loggers = [logger]
// Set up media player view
let vlcView = UIView(frame: self.view.bounds)
self.view.addSubview(vlcView)
mediaPlayer?.drawable = vlcView
}
func setupWebSocket() {
// Configure WebSocket
let request = URLRequest(url: URL(string: "wss://rec03ihanoi.vtscloud.vn:443/evup/1727065882jPWLbJ/d12aa2a31aa4xyzummuv07lWh")!)
socket = WebSocket(request: request)
socket.onEvent = { [weak self] event in
switch event {
case .connected:
print("WebSocket connected")
self?.socket.write(string: "")
self?.startStreaming()
case .binary(let data):
print("WebSocket data")
self?.handleWebSocketData(data: data)
default:
()
}
}
socket.connect()
}
func handleWebSocketData(data: Data) {
// Append WebSocket data to the input stream
if webSocketStream != nil {
webSocketStream.append(data)
}
}
func startStreaming() {
// Create and open a WebSocketInputStream
webSocketStream = WebSocketInputStream()
webSocketStream.open()
// Create a VLCMedia object with the custom input stream
let vlcMedia = VLCMedia(stream: webSocketStream)
vlcMedia.addOption("-vv")
vlcMedia.addOption("--codec=h265")
mediaPlayer.media = vlcMedia
// Start the media player
mediaPlayer.play()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
socket.disconnect() // Disconnect WebSocket when view disappears
mediaPlayer.stop() // Stop the media player when the view disappears
}
}
Upvotes: 0
Views: 58