func SinglePlayProcess(fpath string, loop *C.GMainLoop) { // fmt.Printf("filename[%s]\n", fpath) var pipeline *C.GstElement // 定义组件 var bus *C.GstBus v0 := GString("playbin") v1 := GString("play") pipeline = C.gst_element_factory_make(v0, v1) GFree(unsafe.Pointer(v0)) GFree(unsafe.Pointer(v1)) v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) // 得到 管道的消息总线 bus = C.pipeline_get_bus(unsafe.Pointer(pipeline)) if bus == (*C.GstBus)(nil) { fmt.Println("GstBus element could not be created.Exiting.") return } C.bus_add_watch(unsafe.Pointer(bus), unsafe.Pointer(loop)) C.mp3_ready(unsafe.Pointer(pipeline)) C.mp3_play(unsafe.Pointer(pipeline)) // 开始循环 C.g_main_loop_run(loop) C.mp3_stop(unsafe.Pointer(pipeline)) C.object_unref(unsafe.Pointer(pipeline)) }
// TODO: Move ElementFactoryMake to element_factory.go func ElementFactoryMake(factory_name, name string) *Element { fn := (*C.gchar)(C.CString(factory_name)) defer C.free(unsafe.Pointer(fn)) n := (*C.gchar)(C.CString(name)) defer C.free(unsafe.Pointer(n)) e := new(Element) e.SetPtr(glib.Pointer(C.gst_element_factory_make(fn, n))) return e }
func NewElement(factory string, name string) (*C.GstElement, error) { cFactory := toGStr(factory) cName := toGStr(name) element := C.gst_element_factory_make(cFactory, cName) if element == nil { return nil, errors.New(fmt.Sprintf("failed to create element %s:%s", factory, name)) } runtime.SetFinalizer(element, func(e *C.GstElement) { C.gst_object_unref(asGPtr(element)) }) return element, nil }
// ElementFactoryMake() is a wrapper around gst_element_factory_make(). func ElementFactoryMake(factoryName, name string) (*Element, error) { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) cfactoryName := C.CString(factoryName) defer C.free(unsafe.Pointer(cfactoryName)) c := C.gst_element_factory_make((*C.gchar)(cfactoryName), (*C.gchar)(cname)) if c == nil { return nil, nilPtrErr } obj := &glib.Object{glib.ToGObject(unsafe.Pointer(c))} b := wrapElement(obj) b.RefSink() runtime.SetFinalizer(&b.Object, (*Object).Unref) return b, nil }
func PlayProcess(cs chan byte, loop *C.GMainLoop) { wg := new(sync.WaitGroup) sig_out := make(chan bool) defer close(sig_out) defer g_wg.Done() if g_isOutOfOrder { outOfOrder(g_list) debug.FreeOSMemory() } start := g_list.Front() end := g_list.Back() e := g_list.Front() for { fpath, ok := e.Value.(string) if ok { // fmt.Printf("filename[%s]\n", fpath) var pipeline *C.GstElement // 定义组件 var bus *C.GstBus v0 := GString("playbin") v1 := GString("play") pipeline = C.gst_element_factory_make(v0, v1) GFree(unsafe.Pointer(v0)) GFree(unsafe.Pointer(v1)) v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) // 得到 管道的消息总线 bus = C.pipeline_get_bus(unsafe.Pointer(pipeline)) if bus == (*C.GstBus)(nil) { fmt.Println("GstBus element could not be created.Exiting.") return } C.bus_add_watch(unsafe.Pointer(bus), unsafe.Pointer(loop)) C.mp3_ready(unsafe.Pointer(pipeline)) C.mp3_play(unsafe.Pointer(pipeline)) wg.Add(1) go func(p *C.GstElement) { defer wg.Done() // 开始循环 C.g_main_loop_run(loop) C.mp3_stop(unsafe.Pointer(p)) C.object_unref(unsafe.Pointer(p)) e = e.Next() if e == nil { sig_out <- true } else { sig_out <- false } }(pipeline) lb := true for lb { select { case op := <-cs: switch op { case 's': C.mp3_pause(unsafe.Pointer(pipeline)) case 'r': C.mp3_play(unsafe.Pointer(pipeline)) case 'n': if e != end { e = e.Next() } C.g_main_loop_quit(loop) case 'p': if e != start { e = e.Prev() } C.g_main_loop_quit(loop) case 'q': C.g_main_loop_quit(loop) <-sig_out wg.Wait() return } case c := <-sig_out: if c { wg.Wait() return } else { lb = false } } } wg.Wait() } else { // 路径非法 return } } }
func mp3_play_process(cs chan byte, loop *C.GMainLoop) { wg := new(sync.WaitGroup) sig_in := make(chan bool) sig_out := make(chan bool) defer close(sig_in) defer close(sig_out) defer g_wg.Done() if g_isOutOfOrder { outOfOrder(g_list) debug.FreeOSMemory() } start := g_list.Front() end := g_list.Back() e := g_list.Front() for { fpath, ok := e.Value.(string) if ok { // fmt.Printf("filename[%s]\n", fpath) var pipeline, source, decoder, sink *C.GstElement // 定义组件 var bus *C.GstBus switch filepath.Ext(fpath) { case ".mp3": v3 := GString("mad") v4 := GString("mad-decoder") decoder = C.gst_element_factory_make(v3, v4) GFree(C.gpointer(v4)) GFree(C.gpointer(v3)) case ".wav": v3 := GString("wavparse") v4 := GString("parser") decoder = C.gst_element_factory_make(v3, v4) GFree(C.gpointer(v3)) GFree(C.gpointer(v4)) case ".ogg": // v3 := GString("oggparse") // defer GFree(C.gpointer(v3)) // v4 := GString("ogg-parser") // defer GFree(C.gpointer(v4)) // decoder = C.gst_element_factory_make(v3, v4) fallthrough default: return } // fmt.Printf("FileName[%s]FileSize[%d]Dir[%v]\n", path, info.Size(), info.IsDir()) // 创建管道和组件 v0 := GString("audio-player") pipeline = C.gst_pipeline_new(v0) GFree(C.gpointer(v0)) v1 := GString("filesrc") v2 := GString("file-source") source = C.gst_element_factory_make(v1, v2) GFree(C.gpointer(v1)) GFree(C.gpointer(v2)) // sink = gst_element_factory_make("autoaudiosink","audio-output"); v5 := GString("alsasink") v6 := GString("alsa-output") sink = C.gst_element_factory_make(v5, v6) GFree(C.gpointer(v6)) GFree(C.gpointer(v5)) if pipeline == (*C.GstElement)(nil) || source == (*C.GstElement)(nil) || decoder == (*C.GstElement)(nil) || sink == (*C.GstElement)(nil) { fmt.Println("One element could not be created.Exiting.") } // 设置 source的location 参数。即 文件地址. v7 := GString("location") cpath := GString(fpath) C.obj_set(unsafe.Pointer(source), unsafe.Pointer(v7), unsafe.Pointer(cpath)) GFree(C.gpointer(v7)) GFree(C.gpointer(cpath)) // 得到 管道的消息总线 bus = C.pipeline_get_bus(unsafe.Pointer(pipeline)) if bus == (*C.GstBus)(nil) { fmt.Println("GstBus element could not be created.Exiting.") return } // 添加消息监视器 C.bus_add_watch(unsafe.Pointer(bus), unsafe.Pointer(loop)) C.gst_object_unref(C.gpointer(bus)) // 把组件添加到管道中.管道是一个特殊的组件,可以更好的让数据流动 C.bin_add_many(unsafe.Pointer(pipeline), unsafe.Pointer(source), unsafe.Pointer(decoder), unsafe.Pointer(sink)) // 依次连接组件 C.element_link_many(unsafe.Pointer(source), unsafe.Pointer(decoder), unsafe.Pointer(sink)) // 开始播放 C.mp3_ready(unsafe.Pointer(pipeline)) C.mp3_play(unsafe.Pointer(pipeline)) wg.Add(1) go func(p *C.GstElement) { defer wg.Done() // 开始循环 C.g_main_loop_run(loop) C.mp3_stop(unsafe.Pointer(p)) C.object_unref(unsafe.Pointer(p)) select { case c := <-sig_in: if c { return } default: e = e.Next() if e == nil { sig_out <- true return } } sig_out <- false }(pipeline) lb := true for lb { select { case op := <-cs: switch op { case 's': C.mp3_pause(unsafe.Pointer(pipeline)) case 'r': C.mp3_play(unsafe.Pointer(pipeline)) case 'n': if e != end { e = e.Next() } C.g_main_loop_quit(loop) sig_in <- false case 'p': if e != start { e = e.Prev() } C.g_main_loop_quit(loop) sig_in <- false case 'q': C.g_main_loop_quit(loop) sig_in <- true wg.Wait() return } case c := <-sig_out: if c { return } else { lb = false } } } wg.Wait() } } }
func PlayProcess(cs chan byte, loop *C.GMainLoop) { var pipeline *C.GstElement // 定义组件 var bus *C.GstBus wg := new(sync.WaitGroup) sig_out := make(chan bool) g_wg.Add(1) defer close(sig_out) defer g_wg.Done() if g_isOutOfOrder { outOfOrder(g_list) debug.FreeOSMemory() } start := g_list.Front() end := g_list.Back() e := g_list.Front() v0 := GString("playbin") v1 := GString("play") pipeline = C.gst_element_factory_make(v0, v1) GFree(unsafe.Pointer(v0)) GFree(unsafe.Pointer(v1)) // 得到 管道的消息总线 bus = C.pipeline_get_bus(unsafe.Pointer(pipeline)) if bus == (*C.GstBus)(nil) { fmt.Println("GstBus element could not be created.Exiting.") return } C.bus_add_watch(unsafe.Pointer(bus), unsafe.Pointer(loop)) // 开始循环 go func(sig_quit chan bool) { wg.Add(1) i := 0 LOOP_RUN: for !g_isQuit { if i != 0 { C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } C.g_main_loop_run(loop) C.media_stop(unsafe.Pointer(pipeline)) switch g_play_style { case PLAY_STYLE_SINGLE: sig_quit <- true break LOOP_RUN case PLAY_STYLE_ORDER: if e != end { e = e.Next() } else { break LOOP_RUN } case PLAY_STYLE_SHUFFLE: if e != end { e = e.Next() } else { break LOOP_RUN } case PLAY_STYLE_SLOOP: case PLAY_STYLE_ALOOP: if e != end { e = e.Next() } else { e = start } } fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) } else { break } i++ } C.object_unref(unsafe.Pointer(pipeline)) wg.Done() }(sig_out) fpath, ok := e.Value.(string) if ok { // fmt.Printf("filename[%s]\n", fpath) v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) //C.set_mute(unsafe.Pointer(pipeline)) lb := true for lb { select { case op := <-cs: switch op { case 's': C.media_pause(unsafe.Pointer(pipeline)) case 'r': C.media_play(unsafe.Pointer(pipeline)) case 'n': switch g_play_style { case PLAY_STYLE_SINGLE: lb = false g_isQuit = true case PLAY_STYLE_ORDER: fallthrough case PLAY_STYLE_SHUFFLE: C.media_stop(unsafe.Pointer(pipeline)) if e != end { e = e.Next() } else { lb = false g_isQuit = true } case PLAY_STYLE_SLOOP: C.media_stop(unsafe.Pointer(pipeline)) case PLAY_STYLE_ALOOP: if e != end { e = e.Next() } else { e = start } } if !lb { fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } else { lb = false g_isQuit = true } } //C.g_main_loop_quit(loop) case 'p': switch g_play_style { case PLAY_STYLE_SINGLE: // do nothing ??? case PLAY_STYLE_ORDER: fallthrough case PLAY_STYLE_SHUFFLE: C.media_stop(unsafe.Pointer(pipeline)) if e != start { e = e.Prev() fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } else { lb = false g_isQuit = true } } else { lb = false g_isQuit = true } case PLAY_STYLE_SLOOP: C.media_stop(unsafe.Pointer(pipeline)) fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } case PLAY_STYLE_ALOOP: C.media_stop(unsafe.Pointer(pipeline)) if e != start { e = e.Prev() } else { e = end } fpath, ok := e.Value.(string) if ok { v2 := GString(fpath) C.set_path(unsafe.Pointer(pipeline), v2) GFree(unsafe.Pointer(v2)) C.media_ready(unsafe.Pointer(pipeline)) C.media_play(unsafe.Pointer(pipeline)) } } case 'q': lb = false g_isQuit = true case '+': g_volume_size++ C.set_volume(unsafe.Pointer(pipeline), C.int(g_volume_size)) case '-': g_volume_size-- if g_volume_size < 0 { g_volume_size = 0 } C.set_volume(unsafe.Pointer(pipeline), C.int(g_volume_size)) case 't': C.media_seek(unsafe.Pointer(pipeline), C.gint64(5)) } case vv0 := <-sig_out: if vv0 { C.g_main_loop_quit(loop) wg.Wait() g_wg.Done() g_wg.Wait() close(sig_out) os.Exit(0) } } } } else { // 路径非法 return } C.g_main_loop_quit(loop) wg.Wait() }