我想在UIImageView中显示MJPEG流。
我已经实现了流加载,并通过委托将图像发送到CameraViewModel。
final class CameraViewModel: ObservableObject {
lazy var cameraService = CameraService(delegate: self)
@Published var cameraImage = UIImage(systemName: "cloud.heavyrain.fill")
func play() {
cameraService.play()
}
func stop() {
cameraService.stop()
}
}
extension CameraViewModel: CameraServiceDelegateProtocol {
func frame(image: UIImage) {
cameraImage = image
print("updated image (self.cameraImage!)")
}
}
每个新图像都会按预期调用委托函数,我将其分配给@Published var cameraImage。
在视图端,@Published属性用于填充UIImageView,但图像不会更新。
struct CameraView: View {
@Binding var showCamera: Bool
@ObservedObject var cameraViewModel: CameraViewModel = CameraViewModel()
var body: some View {
VStack {
Image(uiImage: cameraViewModel.cameraImage!).aspectRatio(contentMode: .fit).frame(height: 200)
Button("Close") {
cameraViewModel.stop()
showCamera.toggle()
}.onAppear() {
cameraViewModel.play()
}
}
}
}
VStack中的图像(…(没有更新,我似乎不知道出了什么问题。
供参考,这里是CameraService:
protocol CameraServiceDelegateProtocol {
func frame(image: UIImage) -> Void
}
protocol CameraServiceProtocol {
var rosServiceDelegate: CameraServiceDelegateProtocol { get set }
}
class CameraService: NSObject, ObservableObject {
var cameraServiceDelegate: CameraServiceDelegateProtocol
let realUrl = URL(string: "http://192.168.45.100:8080/stream?topic=/image_raw")
var dataTask: URLSessionDataTask?
var receivedData: NSMutableData = NSMutableData()
var session: URLSession?
init(delegate: CameraServiceDelegateProtocol) {
cameraServiceDelegate = delegate
}
func play() {
session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
dataTask = session?.dataTask(with: realUrl!)
dataTask?.resume()
}
func stop() {
dataTask?.cancel()
}
}
extension CameraService: URLSessionDataDelegate {
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
if self.receivedData.length > 0,
let receivedImage = UIImage(data: self.receivedData as Data) {
DispatchQueue.main.async {
self.cameraServiceDelegate.frame(image: receivedImage)
}
self.receivedData = NSMutableData()
}
completionHandler(URLSession.ResponseDisposition.allow) //.Cancel,If you want to stop the download
}
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
self.receivedData.append(data)
}
}
在CameraView
中替换
@ObservedObject var cameraViewModel
带有
@StateObject var cameraViewModel