使用go语言编写一个播放器,直接看效果
整体思路是使用ffmpeg解码,然后使用xui进行渲染,音频播放暂时还没调通,以下是源码
package main
import (
"github.com/nareix/joy4/av"
"github.com/nareix/joy4/av/avutil"
"github.com/nareix/joy4/cgo/ffmpeg"
"github.com/nareix/joy4/format"
"github.com/tenny1225/xui"
"image"
"math"
"time"
)
type TestView struct {
*xui.View
img *image.YCbCr
}
func (v *TestView) Draw(canvas xui.XCanvas) {
if v.img == nil {
return
}
iw, ih := float64((*v.img).Bounds().Dx()), float64((*v.img).Bounds().Dy())
w, h := v.Window.GetSize()
s := math.Min(float64(w)/iw, float64(h)/ih)
canvas.Save()
canvas.SetScale(s, s)
canvas.DrawImage(-(iw - float64(w))/2, -(ih - float64(h))/2, (*v.img).SubImage((*v.img).Bounds()))
canvas.Restore()
}
//func (v *TestView) MeasureSize(w, h float64) (float64, float64) {
// return math.MaxFloat64, math.MaxFloat64
//}
func NewTestView(v *xui.View) xui.Viewer {
view := &TestView{v, nil}
view.Drawer = view.Draw
//view.Measurer = view.MeasureSize
return view
}
type TestPage struct {
xui.BasePage
Root xui.Viewer
}
func (p *TestPage) GetContentView() xui.Viewer {
p.Root = NewTestView(&xui.View{
Top: 10,
Left: 10,
FontPath: "OPPOSans-M.ttf",
FontSize: 15,
Title: "hello world",
PaddingLeft: 8,
PaddingTop: 8,
PaddingRight: 8,
PaddingBottom: 8,
})
return p.Root
}
func (p *TestPage) Create(data map[string]interface{}) {
go func() {
avfile, _ := avutil.Open("/home/xz/桌面/movie.mp4")
streams, _ := avfile.Streams()
var videoDecoder *ffmpeg.VideoDecoder
for _, stream := range streams {
if stream.Type().IsVideo() {
vstream := stream.(av.VideoCodecData)
videoDecoder, _ = ffmpeg.NewVideoDecoder(vstream)
//fmt.Println(vstream.Type(), vstream.Width(), vstream.Height())
}
}
for {
pkt, e := avfile.ReadPacket()
if e != nil {
return
}
vframe, e := videoDecoder.Decode(pkt.Data)
if e == nil {
v := p.Root.(*TestView)
v.img = &vframe.Image
}
time.Sleep(time.Millisecond * 22)
//}
}
avfile.Close()
}()
}
func main() {
ctx := xui.NewXContext()
ctx.Run(func() {
w := xui.NewWindow("测试", 400, 400, 500, 500, true, ctx)
w.AddRoute("test", &TestPage{})
w.StartPage("test", nil, false)
})
}
func init() {
format.RegisterAll()
}