示例#1
0
文件: mp3decode.go 项目: hwch/go-dev
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
		}

	}
}
示例#2
0
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()
		}

	}
}