@@ -432,6 +432,7 @@ internal constructor(
432432     * 
433433     * @param track The track to publish. 
434434     * @param options The publish options to use, or [Room.audioTrackPublishDefaults] if none is passed. 
435+      * @return true if the track published successfully 
435436     */  
436437    suspend  fun  publishAudioTrack (
437438        track :  LocalAudioTrack ,
@@ -441,25 +442,35 @@ internal constructor(
441442        ).copy(preconnect = defaultsManager.isPrerecording),
442443        publishListener :  PublishListener ?  = null,
443444    ): Boolean  {
445+         if  (track.isDisposed) {
446+             LKLog .w { " Attempting to publish a disposed track, ignoring." 
447+             return  false 
448+         }
449+ 
444450        val  encodings =  listOf (
445451            RtpParameters .Encoding (null , true , null ).apply  {
446452                if  (options.audioBitrate !=  null  &&  options.audioBitrate >  0 ) {
447453                    maxBitrateBps =  options.audioBitrate
448454                }
449455            },
450456        )
451-         val  publication =  publishTrackImpl(
452-             track =  track,
453-             options =  options,
454-             requestConfig =  {
455-                 disableDtx =  ! options.dtx
456-                 disableRed =  ! options.red
457-                 addAllAudioFeatures(options.getFeaturesList())
458-                 source =  options.source?.toProto() ? :  LivekitModels .TrackSource .MICROPHONE 
459-             },
460-             encodings =  encodings,
461-             publishListener =  publishListener,
462-         )
457+         var  publication:  LocalTrackPublication ?  =  null 
458+         try  {
459+             publication =  publishTrackImpl(
460+                 track =  track,
461+                 options =  options,
462+                 requestConfig =  {
463+                     disableDtx =  ! options.dtx
464+                     disableRed =  ! options.red
465+                     addAllAudioFeatures(options.getFeaturesList())
466+                     source =  options.source?.toProto() ? :  LivekitModels .TrackSource .MICROPHONE 
467+                 },
468+                 encodings =  encodings,
469+                 publishListener =  publishListener,
470+             )
471+         } catch  (e:  TrackException .PublishException ) {
472+             LKLog .e(e) { " Error thrown when publishing track:" 
473+         }
463474
464475        if  (publication !=  null ) {
465476            val  job =  scope.launch {
@@ -478,6 +489,7 @@ internal constructor(
478489     * 
479490     * @param track The track to publish. 
480491     * @param options The publish options to use, or [Room.videoTrackPublishDefaults] if none is passed. 
492+      * @return true if the track published successfully 
481493     */  
482494    suspend  fun  publishVideoTrack (
483495        track :  LocalVideoTrack ,
@@ -489,6 +501,17 @@ internal constructor(
489501    ): Boolean  {
490502        @Suppress(" NAME_SHADOWING" var  options =  options
491503
504+         if  (track.isDisposed) {
505+             LKLog .w { " Attempting to publish a disposed track, ignoring." 
506+             return  false 
507+         }
508+ 
509+         val  rtcTrackId =  track.withRTCTrack(null ) { id() }
510+         if  (rtcTrackId ==  null ) {
511+             LKLog .w { " Attempting to publish a disposed track, ignoring." 
512+             return  false 
513+         }
514+ 
492515        synchronized(enabledPublishVideoCodecs) {
493516            if  (enabledPublishVideoCodecs.isNotEmpty()) {
494517                if  (enabledPublishVideoCodecs.none { allowedCodec ->  allowedCodec.mime.mimeTypeToVideoCodec() ==  options.videoCodec }) {
@@ -522,40 +545,47 @@ internal constructor(
522545        val  videoLayers = 
523546            EncodingUtils .videoLayersFromEncodings(track.dimensions.width, track.dimensions.height, encodings, isSVC)
524547
525-         return  publishTrackImpl(
526-             track =  track,
527-             options =  options,
528-             requestConfig =  {
529-                 width =  track.dimensions.width
530-                 height =  track.dimensions.height
531-                 source =  options.source?.toProto() ? :  if  (track.options.isScreencast) {
532-                     LivekitModels .TrackSource .SCREEN_SHARE 
533-                 } else  {
534-                     LivekitModels .TrackSource .CAMERA 
535-                 }
536-                 addAllLayers(videoLayers)
548+         var  publication:  LocalTrackPublication ?  =  null 
549+         try  {
550+             publication =  publishTrackImpl(
551+                 track =  track,
552+                 options =  options,
553+                 requestConfig =  {
554+                     width =  track.dimensions.width
555+                     height =  track.dimensions.height
556+                     source =  options.source?.toProto() ? :  if  (track.options.isScreencast) {
557+                         LivekitModels .TrackSource .SCREEN_SHARE 
558+                     } else  {
559+                         LivekitModels .TrackSource .CAMERA 
560+                     }
561+                     addAllLayers(videoLayers)
537562
538-                 addSimulcastCodecs(
539-                     with (SimulcastCodec .newBuilder()) {
540-                         codec =  options.videoCodec
541-                         cid =  track.rtcTrack.id()
542-                         build()
543-                     },
544-                 )
545-                 //  set up backup codec
546-                 if  (options.backupCodec?.codec !=  null  &&  options.videoCodec !=  options.backupCodec?.codec) {
547563                    addSimulcastCodecs(
548564                        with (SimulcastCodec .newBuilder()) {
549-                             codec =  options.backupCodec !! .codec 
550-                             cid =  " " 
565+                             codec =  options.videoCodec 
566+                             cid =  rtcTrackId 
551567                            build()
552568                        },
553569                    )
554-                 }
555-             },
556-             encodings =  encodings,
557-             publishListener =  publishListener,
558-         ) !=  null 
570+                     //  set up backup codec
571+                     if  (options.backupCodec?.codec !=  null  &&  options.videoCodec !=  options.backupCodec?.codec) {
572+                         addSimulcastCodecs(
573+                             with (SimulcastCodec .newBuilder()) {
574+                                 codec =  options.backupCodec!! .codec
575+                                 cid =  " " 
576+                                 build()
577+                             },
578+                         )
579+                     }
580+                 },
581+                 encodings =  encodings,
582+                 publishListener =  publishListener,
583+             )
584+         } catch  (e:  TrackException .PublishException ) {
585+             LKLog .e(e) { " Error thrown when publishing track:" 
586+         }
587+ 
588+         return  publication !=  null 
559589    }
560590
561591    private  fun  hasPermissionsToPublish (source :  Track .Source ): Boolean  {
@@ -581,13 +611,19 @@ internal constructor(
581611     * @throws TrackException.PublishException thrown when the publish fails. see [TrackException.PublishException.message] for details. 
582612     * @return true if the track publish was successful. 
583613     */  
614+     @Throws(TrackException .PublishException ::class )
584615    private  suspend  fun  publishTrackImpl (
585616        track :  Track ,
586617        options :  TrackPublishOptions ,
587618        requestConfig :  AddTrackRequest .Builder .() ->  Unit ,
588619        encodings :  List <RtpParameters .Encoding > = emptyList(),
589620        publishListener :  PublishListener ?  = null,
590621    ): LocalTrackPublication ?  {
622+         if  (track.isDisposed) {
623+             LKLog .w { " Attempting to publish a disposed track, ignoring." 
624+             return  null 
625+         }
626+ 
591627        fun  onPublishFailure (e :  TrackException .PublishException , triggerEvent :  Boolean  = true) {
592628            publishListener?.onPublishFailure(e)
593629            if  (triggerEvent) {
@@ -1164,6 +1200,7 @@ internal constructor(
11641200                    continuation.cancel(RpcError .BuiltinRpcError .RESPONSE_TIMEOUT .create())
11651201                }
11661202            }
1203+             responseTimeoutJob //  workaround for lint marking this unused. used in cleanup()
11671204
11681205            pendingResponses[requestId] =  PendingRpcResponse (
11691206                participantIdentity =  destinationIdentity,
0 commit comments