I wish to play a HEVC (h.265) streaming video through WebSocket.
I created a customized InputStream to assemble the VLCMedia object however the participant doesn’t work, solely obtained a black view. Is there a unique approach to initialize the media object or stream the video correctly utilizing MobileVLCKit? I am open to any different options for streaming the video.
import UIKit
import Starscream
import MobileVLCKit
import Basis
class WebSocketInputStream: InputStream {
personal var buffer: Information = Information() // Buffer to carry incoming WebSocket information
personal let bufferLock = NSLock()
personal var streamOpen = false
// MARK: - Append WebSocket information to the buffer
func append(_ information: Information) {
bufferLock.lock()
buffer.append(information)
bufferLock.unlock()
}
// MARK: - InputStream strategies
override var hasBytesAvailable: Bool {
// There are bytes accessible if the buffer just isn't empty
bufferLock.lock()
let accessible = !buffer.isEmpty
bufferLock.unlock()
return accessible
}
// Reads as much as the required max size into the supplied buffer
override func learn(_ buffer: UnsafeMutablePointer, maxLength len: Int) -> Int {
bufferLock.lock()
let readLength = min(len, self.buffer.depend)
if readLength > 0 {
self.buffer.copyBytes(to: buffer, depend: readLength)
self.buffer.removeFirst(readLength)
}
bufferLock.unlock()
return readLength
}
// Open the stream
override func open() {
streamOpen = true
}
// Shut the stream
override func shut() {
streamOpen = false
bufferLock.lock()
buffer.removeAll()
bufferLock.unlock()
}
// MARK: - Implement stream properties required by InputStream
override var streamStatus: Stream.Standing {
return streamOpen ? .open : .closed
}
override var streamError: Error? {
return nil // No particular errors for this easy implementation
}
// You may override different strategies as wanted relying in your necessities.
}
class VideoViewController: UIViewController {
var socket: WebSocket!
var mediaPlayer: VLCMediaPlayer!
var webSocketStream: WebSocketInputStream!
override func viewDidLoad() {
tremendous.viewDidLoad()
// Setup the WebSocket connection
setupWebSocket()
// Initialize the VLC media participant
mediaPlayer = VLCMediaPlayer()
let logger = VLCConsoleLogger()
logger.stage = .debug
logger.formatter.contextFlags = .levelContextModule
mediaPlayer.libraryInstance.loggers = [logger]
// Arrange media participant view
let vlcView = UIView(body: 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] occasion in
swap occasion {
case .linked:
print("WebSocket linked")
self?.socket.write(string: "")
self?.startStreaming()
case .binary(let information):
print("WebSocket information")
self?.handleWebSocketData(information: information)
default:
()
}
}
socket.join()
}
func handleWebSocketData(information: Information) {
// Append WebSocket information to the enter stream
if webSocketStream != nil {
webSocketStream.append(information)
}
}
func startStreaming() {
// Create and open a WebSocketInputStream
webSocketStream = WebSocketInputStream()
webSocketStream.open()
// Create a VLCMedia object with the customized enter stream
let vlcMedia = VLCMedia(stream: webSocketStream)
vlcMedia.addOption("-vv")
vlcMedia.addOption("--codec=h265")
mediaPlayer.media = vlcMedia
// Begin the media participant
mediaPlayer.play()
}
override func viewWillDisappear(_ animated: Bool) {
tremendous.viewWillDisappear(animated)
socket.disconnect() // Disconnect WebSocket when view disappears
mediaPlayer.cease() // Cease the media participant when the view disappears
}
}