Пример #1
0
// playbin
func playbin() {
	pipeline, err := NewElement("playbin", "playbin")
	if err != nil {
		log.Fatal(err)
	}
	uri := os.Args[1]
	if !strings.Contains(uri, "://") {
		uri, err = filepath.Abs(uri)
		if err != nil {
			log.Fatal(err)
		}
		uri = "file://" + uri
	}
	ObjSet(asGObj(pipeline), "uri", uri)

	messages := PipelineWatchBus(asGstPipeline(pipeline))
	go func() {
		for msg := range messages {
			MessageDump(msg)
		}
	}()

	C.gst_element_set_state(pipeline, C.GST_STATE_PLAYING)

	loop := C.g_main_loop_new(nil, False())
	C.g_main_loop_run(loop)
}
Пример #2
0
func MainLoopNew(context *GMainContext, is_running bool) *GMainLoop {
	var ctx *C.GMainContext
	if context != nil {
		ctx = context.MainContext
	}
	return &GMainLoop{C.g_main_loop_new(ctx, bool2gboolean(is_running))}
}
Пример #3
0
func oggplayer() {
	pipeline := C.gst_pipeline_new(toGStr("audio-player"))
	source, err := NewElement("filesrc", "file-source")
	if err != nil {
		log.Fatal(err)
	}
	demuxer, err := NewElement("oggdemux", "ogg-demuxer")
	if err != nil {
		log.Fatal(err)
	}
	decoder, err := NewElement("vorbisdec", "vorbis-decoder")
	if err != nil {
		log.Fatal(err)
	}
	conv, err := NewElement("audioconvert", "converter")
	if err != nil {
		log.Fatal(err)
	}
	sink, err := NewElement("autoaudiosink", "audio-output")
	if err != nil {
		log.Fatal(err)
	}

	ObjSet(asGObj(source), "location", os.Args[1])
	messages := PipelineWatchBus(asGstPipeline(pipeline))
	BinAdd(pipeline, source, demuxer, decoder, conv, sink)
	ElementLink(source, demuxer)
	ElementLink(decoder, conv, sink)
	ObjConnect(asGObj(demuxer), "pad-added", func(elem *C.GstElement, pad *C.GstPad) {
		sink := C.gst_element_get_static_pad(decoder, toGStr("sink"))
		C.gst_pad_link(pad, sink)
		C.gst_object_unref(asGPtr(sink))
	})
	C.gst_element_set_state(pipeline, C.GST_STATE_PLAYING)

	go func() {
		for msg := range messages {
			MessageDump(msg)
		}
	}()

	go func() {
		var pos, length C.gint64
		for _ = range time.NewTicker(time.Second * 1).C {
			C.gst_element_query_position(pipeline, C.GST_FORMAT_TIME, &pos)
			C.gst_element_query_duration(pipeline, C.GST_FORMAT_TIME, &length)
			p("%v / %v\n", time.Duration(pos), time.Duration(length))
			if time.Duration(pos) > time.Second*5 {
				C.gst_element_seek(pipeline, 1.0, C.GST_FORMAT_TIME, C.GST_SEEK_FLAG_FLUSH,
					C.GST_SEEK_TYPE_SET, 10,
					C.GST_SEEK_TYPE_NONE, C.GST_CLOCK_TIME_NONE)
			}
		}
	}()

	loop := C.g_main_loop_new(nil, False())
	C.g_main_loop_run(loop)
}
Пример #4
0
func NewMainLoop(ctx *MainContext) *MainLoop {
	l := new(MainLoop)
	var c *C.GMainContext
	if ctx != nil {
		c = ctx.GMainContext()
	}
	l.SetPtr(Pointer(C.g_main_loop_new(c, 0)))
	return l
}
Пример #5
0
func main() {
	var loop *C.GMainLoop
	var s0 byte
	mdir := ""

	flag.StringVar(&mdir, "mdir", "", "mp3文件目录")
	flag.BoolVar(&g_isOutOfOrder, "rand", false, "是否乱序播放")
	flag.Parse()

	if mdir == "" {
		flag.PrintDefaults()
		return
	}
	g_list = list.New()
	g_wg = new(sync.WaitGroup)
	C.gst_init((*C.int)(unsafe.Pointer(nil)),
		(***C.char)(unsafe.Pointer(nil)))
	loop = C.g_main_loop_new((*C.GMainContext)(unsafe.Pointer(nil)),
		C.gboolean(0)) // 创建主循环,在执行 g_main_loop_run后正式开始循环

	if err := filepath.Walk(mdir, walkFunc); err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	g_wg.Add(1)
	s := make(chan byte)
	defer close(s)
	go mp3_play_process(s, loop)
LOOP0:
	for {
		fmt.Fscanf(os.Stdin, "%c\n", &s0)
		switch s0 {
		case 's':
			s <- s0
		case 'r':
			s <- s0
		case 'n':
			s <- s0
		case 'p':
			s <- s0
		case 'q':
			s <- s0
			break LOOP0
		case 'h':
			fmt.Print("'s' -> 暂停\n" +
				"'r' -> 继续\n" +
				"'n' -> 下一首\n" +
				"'p' -> 上一首\n" +
				"'q' -> 退出\n")
		}
		s0 = 0
	}
	g_wg.Wait()
}
Пример #6
0
// ranged playing
func ranged() {
	pipeline := C.gst_pipeline_new(toGStr("pipeline"))
	src, err := NewElement("uridecodebin", "src")
	if err != nil {
		log.Fatal(err)
	}
	csp, err := NewElement("videoconvert", "csp")
	if err != nil {
		log.Fatal(err)
	}
	vs, err := NewElement("videoscale", "vs")
	if err != nil {
		log.Fatal(err)
	}
	sink, err := NewElement("autovideosink", "sink")
	if err != nil {
		log.Fatal(err)
	}

	ObjSet(asGObj(src), "uri", os.Args[1])
	BinAdd(pipeline, src, csp, vs, sink)
	ElementLink(csp, vs, sink)
	//TODO sinkpad :=

	ObjConnect(asGObj(src), "pad-added", func(e *C.GstElement, pad *C.GstPad) {
		p("====\n")
		PadAddProbe(pad, C.GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, func(info *C.GstPadProbeInfo) C.GstPadProbeReturn {
			p("blocked\n")
			return C.GST_PAD_PROBE_OK
		})
		//C.gst_pad_link(pad, sinkpad)
	})
	ObjConnect(asGObj(src), "no-more-pads", func(e *C.GstElement) {
	})

	C.gst_element_set_state(pipeline, C.GST_STATE_PAUSED)

	messages := PipelineWatchBus(asGstPipeline(pipeline))
	go func() {
		for msg := range messages {
			MessageDump(msg)
		}
	}()

	loop := C.g_main_loop_new(nil, False())
	C.g_main_loop_run(loop)
}
Пример #7
0
func play() {
	// element
	e, err := NewElement("fakesrc", "source")
	if err != nil {
		log.Fatal(err)
	}
	p("%v\n", e)

	name := C.gst_object_get_name(asGstObj(e))
	p("%s\n", fromGStr(name))

	// factory
	factory, err := NewFactory("fakesrc")
	if err != nil {
		log.Fatal(err)
	}
	p("%s\n", fromGStr(C.gst_object_get_name(asGstObj(factory))))
	p("%s\n", fromGStr(C.gst_element_factory_get_metadata(factory, asGStr(C.CString(C.GST_ELEMENT_METADATA_KLASS)))))
	p("%s\n", fromGStr(C.gst_element_factory_get_metadata(factory, asGStr(C.CString(C.GST_ELEMENT_METADATA_DESCRIPTION)))))

	// id pipeline
	pipeline := C.gst_pipeline_new(toGStr("pipeline"))
	source, _ := NewElement("fakesrc", "source")
	filter, _ := NewElement("identity", "filter")
	sink, _ := NewElement("fakesink", "sink")
	BinAdd(pipeline, source, filter, sink)
	ElementLink(source, filter, sink)
	C.gst_element_set_state(pipeline, C.GST_STATE_PLAYING)
	C.gst_element_sync_state_with_parent(filter)

	/*
		// bin
		bin := C.gst_bin_new(toGStr("bin"))
		source, _ = NewElement("fakesrc", "source")
		sink, _ = NewElement("fakesink", "sink")
		BinAdd(bin, source, sink)
		//C.gst_bin_remove(asGstBin(bin), source)
		ElementLink(source, sink)
		BinAdd(pipeline, bin)
		source = C.gst_bin_get_by_name(asGstBin(bin), toGStr("source"))
	*/

	// bus
	messages := PipelineWatchBus(asGstPipeline(pipeline))
	loop := C.g_main_loop_new(nil, 0)
	go func() {
		C.g_main_loop_run(loop)
	}()

	// message
loop:
	for msg := range messages {
		runtime.GC()
		p("=> %s from %s\n", fromGStr(C.gst_message_type_get_name(msg._type)),
			fromGStr(C.gst_object_get_name(asGstObj(msg.src))))
		switch msg._type {

		case C.GST_MESSAGE_ERROR:
			var err *C.GError
			var debug *C.gchar
			C.gst_message_parse_error(msg, &err, &debug)
			p("Error: %s\n%s\n", fromGStr(err.message), fromGStr(debug))
			C.g_error_free(err)
			C.g_free(asGPtr(debug))
			C.g_main_loop_quit(loop)
			break loop
		case C.GST_MESSAGE_WARNING:
		case C.GST_MESSAGE_INFO:

		case C.GST_MESSAGE_EOS:
			C.g_main_loop_quit(loop)
			break loop

		case C.GST_MESSAGE_TAG:
			var tags *C.GstTagList
			C.gst_message_parse_tag(msg, &tags)
			//TagListForeach(tags, ) TODO
			C.gst_tag_list_unref(tags)

		case C.GST_MESSAGE_STATE_CHANGED:
			var newState, oldState C.GstState
			C.gst_message_parse_state_changed(msg, &oldState, &newState, nil)
			p("%s -> %s\n", fromGStr(C.gst_element_state_get_name(oldState)),
				fromGStr(C.gst_element_state_get_name(newState)))

		}
	}
}
Пример #8
0
func play2() {
	pipeline := C.gst_pipeline_new(toGStr("pipeline"))

	source, err := NewElement("filesrc", "source")
	if err != nil {
		log.Fatal(err)
	}
	ObjSet(asGObj(source), "location", os.Args[1])

	demux, err := NewElement("oggdemux", "demuxer")
	if err != nil {
		log.Fatal(err)
	}

	BinAdd(pipeline, source, demux)
	C.gst_element_link_pads(source, toGStr("src"), demux, toGStr("sink"))
	ObjConnect(asGObj(demux), "pad-added", func(demuxer *C.GstElement, pad *C.GstPad) {
		p("pad added %T %v\n", pad, pad)
	})

	// bus
	messages := PipelineWatchBus(asGstPipeline(pipeline))

	C.gst_element_set_state(pipeline, C.GST_STATE_PLAYING)

	loop := C.g_main_loop_new(nil, 0)
	go func() {
	loop:
		for msg := range messages {
			runtime.GC()
			p("=> %s: %s\n", fromGStr(C.gst_object_get_name(asGstObj(msg.src))),
				fromGStr(C.gst_message_type_get_name(msg._type)))
			switch msg._type {

			case C.GST_MESSAGE_ERROR:
				var err *C.GError
				var debug *C.gchar
				C.gst_message_parse_error(msg, &err, &debug)
				p("Error: %s\n%s\n", fromGStr(err.message), fromGStr(debug))
				C.g_error_free(err)
				C.g_free(asGPtr(debug))
				C.g_main_loop_quit(loop)
				break loop
			case C.GST_MESSAGE_WARNING:
			case C.GST_MESSAGE_INFO:

			case C.GST_MESSAGE_EOS:
				C.g_main_loop_quit(loop)
				break loop

			case C.GST_MESSAGE_TAG:
				var tags *C.GstTagList
				C.gst_message_parse_tag(msg, &tags)
				//TagListForeach(tags, ) TODO
				C.gst_tag_list_unref(tags)

			case C.GST_MESSAGE_STATE_CHANGED:
				var newState, oldState C.GstState
				C.gst_message_parse_state_changed(msg, &oldState, &newState, nil)
				p("%s -> %s\n", fromGStr(C.gst_element_state_get_name(oldState)),
					fromGStr(C.gst_element_state_get_name(newState)))

			}

			C.gst_message_unref(msg)
		}
		p("loop break.\n")
	}()

	runtime.LockOSThread()
	C.g_main_loop_run(loop)
	p("quit.\n")
}
Пример #9
0
// pad probe
func probe() {
	pipeline := C.gst_pipeline_new(toGStr("pipeline"))
	src, err := NewElement("videotestsrc", "src")
	if err != nil {
		log.Fatal(err)
	}
	filter, err := NewElement("capsfilter", "filter")
	if err != nil {
		log.Fatal(err)
	}
	csp, err := NewElement("videoconvert", "csp")
	if err != nil {
		log.Fatal(err)
	}
	sink, err := NewElement("xvimagesink", "sink")
	if err != nil {
		log.Fatal(err)
	}

	BinAdd(pipeline, src, filter, csp, sink)
	ElementLink(src, filter, csp, sink)
	C.gst_element_set_state(pipeline, C.GST_STATE_PLAYING)
	messages := PipelineWatchBus(asGstPipeline(pipeline))

	width, height := 640, 480
	filtercaps := NewCapsSimple("video/x-raw",
		"format", "RGB16",
		"width", width,
		"height", height,
		"framerate", Fraction{25, 1})
	ObjSet(asGObj(filter), "caps", filtercaps)
	n := C.gst_caps_get_size(filtercaps)
	structure := C.gst_caps_get_structure(filtercaps, n-1)
	_ = structure
	C.gst_caps_unref(filtercaps)

	pad := C.gst_element_get_static_pad(src, toGStr("src"))
	PadAddProbe(pad, C.GST_PAD_PROBE_TYPE_BUFFER, func(info *C.GstPadProbeInfo) C.GstPadProbeReturn {
		buffer := (*C.GstBuffer)(unsafe.Pointer(info.data))
		buffer = asGstBuffer(C.gst_mini_object_make_writable(asGstMiniObject(buffer)))
		var mapInfo C.GstMapInfo
		C.gst_buffer_map(buffer, &mapInfo, C.GST_MAP_WRITE)
		var ptr []C.guint16
		header := (*reflect.SliceHeader)(unsafe.Pointer(&ptr))
		header.Len = int(mapInfo.size / 2)
		header.Cap = header.Len
		header.Data = uintptr(unsafe.Pointer(mapInfo.data))
		for y := 0; y < height; y++ {
			for x := 0; x < width/2; x++ {
				ptr[x], ptr[width-1-x] = ptr[width-1-x], ptr[x]
			}
			ptr = ptr[width:]
		}
		C.gst_buffer_unmap(buffer, &mapInfo)
		info.data = asGPtr(buffer)
		return C.GST_PAD_PROBE_OK
	})
	C.gst_object_unref(asGPtr(pad))

	go func() {
		for msg := range messages {
			MessageDump(msg)
		}
	}()

	loop := C.g_main_loop_new(nil, False())
	C.g_main_loop_run(loop)
}
Пример #10
0
func main() {
	var loop *C.GMainLoop
	var s0 byte
	mdir := ""
	mfile := ""
	style := ""

	flag.StringVar(&mdir, "dir", "", "mp3文件目录")
	flag.StringVar(&mfile, "file", "", "mp3文件")
	flag.StringVar(&style, "style", "order", "播放方式[顺序:order|乱序:shuffle|单曲:single|单曲循环:sloop|全部循环:aloop]")
	flag.Parse()

	switch style {
	case "shuffle":
		g_isOutOfOrder = true
		g_play_style = PLAY_STYLE_SHUFFLE

	case "order":
		g_play_style = PLAY_STYLE_ORDER
	case "single":
		g_play_style = PLAY_STYLE_SINGLE
	case "sloop":
		g_play_style = PLAY_STYLE_SLOOP
	case "aloop":
		g_play_style = PLAY_STYLE_ALOOP
	default:
		flag.PrintDefaults()
		return
	}
	g_list = list.New()
	if mfile != "" {
		p, err := filepath.Abs(mfile)
		if err != nil {
			fmt.Printf("Error: %v\n", err)
			return
		}
		C.gst_init((*C.int)(unsafe.Pointer(nil)),
			(***C.char)(unsafe.Pointer(nil)))
		loop = C.g_main_loop_new((*C.GMainContext)(unsafe.Pointer(nil)),
			C.gboolean(0)) // 创建主循环,在执行 g_main_loop_run后正式开始循环
		mfile = fmt.Sprintf("file://%s", p)
		g_list.PushBack(mfile)
		g_play_style = PLAY_STYLE_SINGLE
	} else {
		if mdir == "" {
			flag.PrintDefaults()
			return
		}
		if err := filepath.Walk(mdir, walkFunc); err != nil {
			fmt.Printf("Error: %v\n", err)
			return
		}
	}

	g_wg = new(sync.WaitGroup)
	C.gst_init((*C.int)(unsafe.Pointer(nil)),
		(***C.char)(unsafe.Pointer(nil)))
	loop = C.g_main_loop_new((*C.GMainContext)(unsafe.Pointer(nil)),
		C.gboolean(0)) // 创建主循环,在执行 g_main_loop_run后正式开始循环

	s := make(chan byte)
	defer close(s)
	go PlayProcess(s, loop)

	isQuit := false
	for !isQuit {
		fmt.Fscanf(os.Stdin, "%c\n", &s0)
		switch s0 {
		case 's':
			fallthrough
		case 'r':
			fallthrough
		case 'n':
			fallthrough
		case 'p':
			fallthrough
		case 't':
			fallthrough
		case '+':
			fallthrough
		case '-':
			s <- s0
		case 'q':
			s <- s0
			isQuit = true
		case 'h':
			fmt.Print("'s' -> 暂停\n" +
				"'r' -> 继续\n" +
				"'n' -> 下一首\n" +
				"'p' -> 上一首\n" +
				"'q' -> 退出\n")
		}
		s0 = 0
	}

	g_wg.Wait()

}
Пример #11
0
func g_main_loop_new(context GMainContext, is_running bool) GMainLoop {
	return GMainLoop(C.g_main_loop_new(Arg(context), Arg(Bool2Int[is_running])))
}