package main import ( "log" "path/filepath" "os" "unsafe" ) // #cgo LDFLAGS: -lmpv // #include // #include // #include // mpv_handle* mpvinit(){ // return mpv_create(); // } // int mpvbegin(mpv_handle* mpv, char* src, char* dst) { // mpv_set_property_string(mpv, "o", dst); // mpv_initialize(mpv); // const char *args[3] = {"loadfile", src, NULL}; // return mpv_command(mpv, args); // } // void mpvset(mpv_handle* mpv, char* opt, char* val) { // mpv_set_property_string(mpv, opt, val); // } // mpv_event* mpvwait(mpv_handle* mpv){ // return mpv_wait_event(mpv, 0.25); // } // void mpvend(mpv_handle* mpv){ // mpv_destroy(mpv); // } import "C" func (ctx* ServerContext) MPVConvert(source string, destination string, ext string, options []MPVPair) { defer ctx.WG.Done() dir := filepath.Dir(destination) os.MkdirAll(dir, os.ModePerm) mpv := C.mpvinit() set := func (opt string, val string) { copt := C.CString(opt) defer C.free(unsafe.Pointer(copt)) cval := C.CString(val) defer C.free(unsafe.Pointer(cval)) C.mpvset(mpv, copt, cval) } csrc := C.CString(source) defer C.free(unsafe.Pointer(csrc)) cdst := C.CString(destination) defer C.free(unsafe.Pointer(cdst)) for _, p := range options { set(p.Option, p.Value) } r := C.mpvbegin(mpv, csrc, cdst) if r!=0 { log.Println("mpv error (", source, ", ", destination, ", ", ext, "): ", r) } for C.mpvwait(mpv).event_id!=C.MPV_EVENT_END_FILE { if !ctx.IsActive { C.mpvend(mpv) os.Remove(destination) log.Println("mpv cancelled (", source, ", ", destination, ", ", ext, ")") return } } log.Println("mpv success (", source, ", ", destination, ", ", ext, ")") C.mpvend(mpv) }