(action StreamAction)
| 301 | } |
| 302 | |
| 303 | func (r *Stream) action(action StreamAction) (ok bool) { |
| 304 | var event StateEvent |
| 305 | event.Target = r |
| 306 | event.Action = action |
| 307 | event.From = r.State |
| 308 | event.Time = time.Now() |
| 309 | var next StreamState |
| 310 | if next, ok = event.Next(); ok { |
| 311 | r.State = next |
| 312 | r.SEHistory = append(r.SEHistory, event) |
| 313 | // 给Publisher状态变更的回调,方便进行远程拉流等操作 |
| 314 | var stateEvent any |
| 315 | r.Info(Sprintf("%s%s%s", event.From.String(), Yellow("->"), next.String()), zap.String("action", action.String())) |
| 316 | switch next { |
| 317 | case STATE_WAITPUBLISH: |
| 318 | stateEvent = SEwaitPublish{event, r.Publisher} |
| 319 | waitTime := time.Duration(0) |
| 320 | if r.Publisher != nil { |
| 321 | waitTime = r.Publisher.GetConfig().WaitCloseTimeout |
| 322 | r.Tracks.Range(func(name string, t common.Track) { |
| 323 | t.SetStuff(common.TrackStateOffline) |
| 324 | }) |
| 325 | } |
| 326 | r.Subscribers.OnPublisherLost(event) |
| 327 | if suber := r.Subscribers.Pick(); suber != nil { |
| 328 | r.Subscribers.Broadcast(stateEvent) |
| 329 | if waitTime == 0 { |
| 330 | waitTime = suber.GetSubscriber().Config.WaitTimeout |
| 331 | } |
| 332 | } else if waitTime == 0 { |
| 333 | waitTime = time.Millisecond * 10 //没有订阅者也没有配置发布者等待重连时间,默认10ms后关闭流 |
| 334 | } |
| 335 | r.resetTimer(waitTime) |
| 336 | r.Debug("wait publisher", zap.Duration("wait timeout", waitTime)) |
| 337 | case STATE_WAITTRACK: |
| 338 | if len(r.SEHistory) > 1 { |
| 339 | stateEvent = SErepublish{event} |
| 340 | } else { |
| 341 | stateEvent = SEpublish{event} |
| 342 | } |
| 343 | r.resetTimer(time.Second * 5) // 5秒心跳,检测track的存活度 |
| 344 | case STATE_PUBLISHING: |
| 345 | stateEvent = SEtrackAvaliable{event} |
| 346 | r.Subscribers.SendInviteTrack(r) |
| 347 | r.Subscribers.Broadcast(stateEvent) |
| 348 | if puller, ok := r.Publisher.(IPuller); ok { |
| 349 | puller.OnConnected() |
| 350 | } |
| 351 | r.resetTimer(time.Second * 5) // 5秒心跳,检测track的存活度 |
| 352 | case STATE_WAITCLOSE: |
| 353 | stateEvent = SEwaitClose{event} |
| 354 | if r.IdleTimeout > 0 { |
| 355 | r.resetTimer(r.IdleTimeout) |
| 356 | } else { |
| 357 | r.resetTimer(r.DelayCloseTimeout) |
| 358 | } |
| 359 | case STATE_CLOSED: |
| 360 | Streams.Delete(r.Path) |
no test coverage detected