func (p *MediaPlayer) setPlayState(ps *PlayState, state State, position time.Duration) {
	if ps.State == STATE_BUFFERING {
		position = ps.bufferingPosition
	}
	ps.previousState = ps.State
	ps.State = state
	if state == STATE_BUFFERING {
		ps.bufferingPosition = position
	} else {
		ps.bufferingPosition = -1
	}
	if position == -1 {
		position = p.getPosition(ps)
	}
	p.stateChange <- StateChange{state, position}
}
setPlayState updates the PlayState and sends events.
position may be -1: in that case it will be updated.
package mp
import (
	"time"
)
type MediaPlayer struct {
	player      Backend
	stateChange chan StateChange
	playstateChan chan PlayState
}
func New(stateChange chan StateChange) *MediaPlayer {
	p := MediaPlayer{}
	p.stateChange = stateChange
	p.playstateChan = make(chan PlayState)
	p.player = &Kodi{}
	playerEventChan := p.player.initialize()
	go p.run(playerEventChan, 100)
	return &p
}
func (p *MediaPlayer) Quit() {
	p.getPlayState(func(ps *PlayState) {
		p.player.quit()
	})
}
func (p *MediaPlayer) getPosition(ps *PlayState) time.Duration {
	var position time.Duration
	switch ps.State {
	case STATE_STOPPED:
		position = 0
	case STATE_BUFFERING:
		position = ps.bufferingPosition
	case STATE_PLAYING, STATE_PAUSED:
		position = p.player.getPosition()
	default:
		panic("unknown state")
	}
	if position < 0 {
		panic("got position < 0")
	}
	return position
}
func (p *MediaPlayer) getPlayState(callback func(*PlayState)) {
	ps, ok := <-p.playstateChan
	if !ok {
		return
	}
	callback(&ps)
	p.playstateChan <- ps
}
func (p *MediaPlayer) SetPlaystate(playlist []string, index int, position time.Duration, listId string) {
	p.getPlayState(func(ps *PlayState) {
		if ps.State == STATE_BUFFERING && ps.bufferingPosition == position && ps.Index < len(ps.Playlist) && playlist[index] == ps.Playlist[ps.Index] {
			p.updatePlaylist(ps, playlist)
			return
		}
		ps.Playlist = playlist
		ps.Index = index
		ps.ListId = listId
		if len(ps.Playlist) > 0 {
			p.startPlaying(ps, position)
		} else {
			p.stop(ps)
		}
	})
}
func (p *MediaPlayer) startPlaying(ps *PlayState, position time.Duration) {
	if ps.State == STATE_PLAYING {
		p.player.pause()
	}
	p.setPlayState(ps, STATE_BUFFERING, position)
	videoId := ps.Playlist[ps.Index]
	go func() {
		ps = nil
		p.getPlayState(func(ps *PlayState) {
			if ps.Video() != videoId {
				return
			}
			volume := -1
			if ps.newVolume {
				ps.newVolume = false
				volume = ps.Volume
			}
			p.player.play(videoId, position, volume)
		})
	}()
}
func (p *MediaPlayer) nextVideo(ps *PlayState) {
	if ps.Index+1 < len(ps.Playlist) {
		ps.Index++
		p.startPlaying(ps, 0)
	} else {
		p.setPlayState(ps, STATE_STOPPED, 0)
	}
}
func (p *MediaPlayer) NextVideo() {
	p.getPlayState(func(ps *PlayState) {
		p.nextVideo(ps)
	})
}
func (p *MediaPlayer) previousVideo(ps *PlayState) {
	if ps.Index-1 >= 0 {
		ps.Index--
		p.startPlaying(ps, 0)
	} else {
		p.setPlayState(ps, STATE_STOPPED, 0)
	}
}
func (p *MediaPlayer) PreviousVideo() {
	p.getPlayState(func(ps *PlayState) {
		p.previousVideo(ps)
	})
}