CyCoreSystems / ari

Golang Asterisk REST Interface (ARI) library
Apache License 2.0
180 stars 74 forks source link

Use offsetms on media query #140

Open avraham1 opened 1 year ago

avraham1 commented 1 year ago

I want to play media to the client from a certain point in time. But I can't play media with offsetms.

func playLesson(ctx context.Context, h *ari.ChannelHandle, lessonKey string, offsetms string) { h.Play("", "sound:path/to/file?offsetms=" + offsetms) }

How do you do that? Thanks in advance

Ulexus commented 1 year ago

It looks like we need to add support for something like PlayOptions; we don't expose that right now. It shouldn't be too disruptive to just tack a PlayOptions... to the end of the channel (and bridge) Play functions and interfaces.

avraham1 commented 1 year ago

Thank you.

Do you have an estimate of when you will be able to add it?

Ulexus commented 1 year ago

No, but PRs are always welcome.

Ulexus commented 1 year ago

Also we do offer consulting and programming services, if you wish.

serfreeman1337 commented 1 year ago

I'm sorry that I'm completely forgot about additional params in https://github.com/CyCoreSystems/ari/pull/142. Before api get tagged, what about changing it from variadic function to interface instead ?

Play(key *Key, playbackID string, opts interface{}) (*PlaybackHandle, error)
type PlaybackOptions struct {
    // Media URIs to play.
    Media []string `json:"media"`

    // For sounds, selects language for sound.
    Lang string `json:"lang,omitempty"`

    // Number of milliseconds to skip before playing. Only applies to the first URI if multiple media URIs are specified.
    OffsetMs int `json:"offsetms,omitempty"`

    // Number of milliseconds to skip for forward/reverse operations.
    SkipMs int `json:"skipms,omitempty"`
}
// StagePlay stages a `Play` operation on the bridge
func (c *Channel) StagePlay(key *ari.Key, playbackID string, opts interface{}) (*ari.PlaybackHandle, error) {
    if playbackID == "" {
        playbackID = rid.New(rid.Playback)
    }

    resp := make(map[string]interface{})

    var req interface{}

    switch v := opts.(type) {
    case string:
        req = struct {
            Media string `json:"media"`
        }{
            Media: v,
        }
    case ari.PlaybackOptions:
        req = v
    }

    playbackKey := c.client.stamp(ari.NewKey(ari.PlaybackKey, playbackID))

    return ari.NewPlaybackHandle(playbackKey, c.client.Playback(), func(pb *ari.PlaybackHandle) error {
        return c.client.post("/channels/"+key.ID+"/play/"+playbackID, &resp, &req)
    }), nil
}

This way will keep backward compatibility with v5 api:


 // v5 api (will be still valid with v6)
h.Play("myPlaybackID", "sound:hello-world")

// v6 api
h.Play("myPlaybackID", ari.PlaybackOptions{
    Media: []string{"hello-world"}, 
    Lang: "en", 
    OffsetMs: 750,
})
h.Play("myPlaybackID", ari.PlaybackOptions{
    Media: []string{"sound:your", "sound:extension", "sound:number", "sound:is", "digits:123"}, 
})