Luminate/Sources/LuminatePlayer/VideoPlayerWidget.swift

115 lines
4.3 KiB
Swift

import Adwaita
import CAdw
import CMPV
struct VideoPlayerWidget: Widget {
var url: String
@Binding var isPlaying: Bool
@Binding var position: Double
@Binding var duration: Double
func container<Data>(
data: WidgetData,
type: Data.Type
) -> ViewStorage where Data: ViewRenderData {
let glArea = gtk_gl_area_new()!
gtk_gl_area_set_required_version(glArea, 3, 2)
gtk_gl_area_set_auto_render(glArea, true)
let mpv = mpv_create()!
mpv_set_option_string(mpv, "vo", "gpu")
mpv_set_option_string(mpv, "hwdec", "auto")
mpv_initialize(mpv)
let mpvPtr = Unmanaged.passRetained(mpv as AnyObject).toOpaque()
g_object_set_data(glArea, "mpv", mpvPtr)
g_signal_connect_data(glArea, "realize", GCallback(c_realize), mpvPtr, nil, G_CONNECT_AFTER)
g_signal_connect_data(glArea, "render", GCallback(c_render), mpvPtr, nil, G_CONNECT_AFTER)
g_signal_connect_data(glArea, "unrealize", GCallback(c_unrealize), mpvPtr, nil, G_CONNECT_AFTER)
return ViewStorage(glArea.pointee.widget.pointee.opaque())
}
func update<Data>(
_ storage: ViewStorage,
data: WidgetData,
updateProperties: Bool,
type: Data.Type
) where Data: ViewRenderData {
let ptr = storage.opaquePointer?.opaque(WidgetData.self)
guard let ptr else { return }
}
}
private func c_realize(widget: UnsafeMutableRawPointer?, data: UnsafeMutableRawPointer?) {
guard let widget, let data else { return }
let glArea = widget.opaque(OpaquePointer.self)
gtk_gl_area_make_current(glArea)
let mpv = Unmanaged<AnyObject>.fromOpaque(data).takeUnretainedValue()
let mpvHandle = mpv.opaque(OpaquePointer.self)
var initParams = mpv_opengl_init_params(
get_proc_address: mpv_get_proc_address,
get_proc_address_ctx: nil
)
withUnsafeMutablePointer(to: &initParams) { params in
var renderParams: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_INITIALIZATION_PARAMS, data: params),
mpv_render_param()
]
var renderContext: OpaquePointer?
mpv_render_context_create(&renderContext, mpvHandle, &renderParams)
if let renderContext {
let ctxPtr = Unmanaged.passRetained(renderContext as AnyObject).toOpaque()
g_object_set_data(glArea, "mpv-render-context", ctxPtr)
}
}
}
private func c_render(widget: UnsafeMutableRawPointer?, data: UnsafeMutableRawPointer?) -> Bool {
guard let widget else { return false }
let glArea = widget.opaque(OpaquePointer.self)
guard let ctxPtr = g_object_get_data(glArea, "mpv-render-context") else { return false }
let renderContext = Unmanaged<AnyObject>.fromOpaque(ctxPtr).takeUnretainedValue()
let renderCtx = renderContext.opaque(OpaquePointer.self)
var fbo: Int32 = 0
glGetIntegerv(GLenum(GL_FRAMEBUFFER_BINDING), &fbo)
var dims: [Int32] = [0, 0]
dims[0] = gtk_widget_get_width(gtk_widget_get_parent(glArea))
dims[1] = gtk_widget_get_height(gtk_widget_get_parent(glArea))
var renderParams: [mpv_render_param] = [
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: &fbo),
mpv_render_param(type: MPV_RENDER_PARAM_FLIP_Y, data: [Int32(1)]),
mpv_render_param(type: MPV_RENDER_PARAM_PRESENT_FENCE, data: [Int32(0)]),
mpv_render_param()
]
mpv_render_context_render(renderCtx, &renderParams)
return true
}
private func c_unrealize(widget: UnsafeMutableRawPointer?, data: UnsafeMutableRawPointer?) {
guard let widget else { return }
let glArea = widget.opaque(OpaquePointer.self)
if let ctxPtr = g_object_get_data(glArea, "mpv-render-context") {
let renderContext = Unmanaged<AnyObject>.fromOpaque(ctxPtr).takeUnretainedValue()
let renderCtx = renderContext.opaque(OpaquePointer.self)
mpv_render_context_free(renderCtx)
}
if let mpvPtr = g_object_get_data(glArea, "mpv") {
let mpv = Unmanaged<AnyObject>.fromOpaque(mpvPtr).takeUnretainedValue()
let mpvHandle = mpv.opaque(OpaquePointer.self)
mpv_terminate_destroy(mpvHandle)
}
}
private func mpv_get_proc_address(
_ ctx: UnsafeMutableRawPointer?,
_ name: UnsafePointer<CChar>?
) -> UnsafeMutableRawPointer? {
guard let name else { return nil }
return glXGetProcAddress(name)
}