Hi,
I got slow performance when adding ProgressComponent. I use this component to show current position status and slider for position indicator.
And sometimes i can't interact with other component, such as my play/pause button. is this RN problem or the library?
Here is my code:
export class TrackStatus extends TrackPlayer.ProgressComponent {
state = {
duration: 0,
isSeeking: false
}
formatTime(seconds) {
return seconds > 3600
?
[
parseInt(seconds / 60 / 60),
parseInt(seconds / 60 % 60),
parseInt(seconds % 60)
].join(":").replace(/\b(\d)\b/g, "0$1")
:
[
parseInt(seconds / 60 % 60),
parseInt(seconds % 60)
].join(":").replace(/\b(\d)\b/g, "0$1")
}
render () {
TrackPlayer.getDuration().then(duration=>this.setState({duration}))
return (
<View>
<View style={{flexDirection:'row',paddingHorizontal: 15,alignItems:'center'}}>
<Text style={{color: 'white',backgroundColor:'transparent',width:40,textAlign:'center',fontSize:12}}>
{ this.state.isSeeking ? this.formatTime(this.seek) : this.formatTime(this.state.position) }
</Text>
<Slider
minimumValue = {0}
maximumValue = {this.state.duration}
thumbTintColor = "white"
minimumTrackTintColor = "#f06595"
maximumTrackTintColor = "rgba(255,255,255,.8)"
step = {1}
onValueChange ={ val=>{
TrackPlayer.pause();
this.seek = val;
this.setState({isSeeking:true})
}}
onSlidingComplete={ val=>{
this.setState({isSeeking: false },()=> {
TrackPlayer.seekTo(this.seek);
this.position = this.seek;
TrackPlayer.play();
})
}}
value={this.state.isSeeking ? this.seek : this.state.position}
/>
<Text>{this.formatTime(this.state.duration)}</Text>
</View>
</View>
)
}
}
Thanks.
this.state.duration instead.You can check out an example here
Thanks. Any idea how to implement the slider for seek control without slowing the app?
This is slightly unrelated, but the only slider in my app is for this progress component. Also the most-frequent crash in my Android app seems to be related to sliders...
java.lang.NullPointerException:
at android.animation.AnimatorSet.clone (AnimatorSet.java:690)
at android.animation.AnimatorSet.clone (AnimatorSet.java:51)
at android.animation.Animator$AnimatorConstantState.newInstance (Animator.java:562)
at android.animation.Animator$AnimatorConstantState.newInstance (Animator.java:543)
at android.content.res.ConstantState.newInstance (ConstantState.java:51)
at android.content.res.ConstantState.newInstance (ConstantState.java:59)
at android.animation.AnimatorInflater.loadAnimator (AnimatorInflater.java:133)
at android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator.newInstance (AnimatedVectorDrawable.java:567)
at android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState.inflatePendingAnimators (AnimatedVectorDrawable.java:545)
at android.graphics.drawable.AnimatedVectorDrawable.applyTheme (AnimatedVectorDrawable.java:377)
at android.graphics.drawable.DrawableContainer$DrawableContainerState.applyTheme (DrawableContainer.java:865)
at android.graphics.drawable.DrawableContainer.applyTheme (DrawableContainer.java:577)
at android.graphics.drawable.StateListDrawable.applyTheme (StateListDrawable.java:370)
at android.graphics.drawable.AnimatedStateListDrawable.applyTheme (AnimatedStateListDrawable.java:391)
at android.content.res.Resources.loadDrawable (Resources.java:2589)
at android.content.res.MiuiResources.loadDrawable (MiuiResources.java:387)
at android.content.res.TypedArray.getDrawable (TypedArray.java:872)
at android.widget.AbsSeekBar.<init> (AbsSeekBar.java:92)
at android.widget.SeekBar.<init> (SeekBar.java:85)
at android.widget.SeekBar.<init> (SeekBar.java:81)
at com.facebook.react.views.slider.ReactSlider.<init> (ReactSlider.java:56)
at com.facebook.react.views.slider.ReactSliderManager.createViewInstance (ReactSliderManager.java:121)
at com.facebook.react.views.slider.ReactSliderManager.createViewInstance (ReactSliderManager.java:39)
at com.facebook.react.uimanager.ViewManager.createView (ViewManager.java:44)
at com.facebook.react.uimanager.NativeViewHierarchyManager.createView (NativeViewHierarchyManager.java:224)
at com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute (UIViewOperationQueue.java:153)
at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.dispatchPendingNonBatchedOperations (UIViewOperationQueue.java:1010)
at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded (UIViewOperationQueue.java:981)
at com.facebook.react.uimanager.GuardedFrameCallback.doFrame (GuardedFrameCallback.java:31)
at com.facebook.react.modules.core.ReactChoreographer$ReactChoreographerDispatcher.doFrame (ReactChoreographer.java:136)
at com.facebook.react.modules.core.ChoreographerCompat$FrameCallback$1.doFrame (ChoreographerCompat.java:107)
at android.view.Choreographer$CallbackRecord.run (Choreographer.java:858)
at android.view.Choreographer.doCallbacks (Choreographer.java:672)
at android.view.Choreographer.doFrame (Choreographer.java:605)
at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:846)
at android.os.Handler.handleCallback (Handler.java:742)
at android.os.Handler.dispatchMessage (Handler.java:95)
at android.os.Looper.loop (Looper.java:154)
at android.app.ActivityThread.main (ActivityThread.java:5523)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:629)
@ariona Also, don't setState in render method. This... TrackPlayer.getDuration().then(duration=>this.setState({duration})) will create at least one infinite loop. More if the component receives other props/store-state that change.
This issue has been inactive for a while and seems that the issue was resolved. I will now close it.
Just started using the ProgressComponent, it still retrieves position values even when the player stopped. This seems quite unnecessary or am I wrong?
@Pczek & Anyone still facing this issue. The latest 1.1.4 has this.state.position, this.state.duration, and this.state.bufferedPosition returning correctly for each Platform.
You're progress component will still update when the track player is stopped which I think is the correct behavior because those values could realistically change without the audio playing and you would want to update them.
To improve performance simply drop in a shouldComponentUpdate where ever you extend ProgressComponent
class MyProgressComponent extends ProgressComponent {
shouldComponentUpdate(nextProps, nextState) {
const {
duration: prevDuration,
position: prevPosition,
bufferedPosition: prevBufferedPosition
} = this.state;
const {
duration: nextDuration,
position: nextPosition,
bufferedPosition: nextBufferedPosition
} = nextState;
if(prevDuration !== nextDuration || prevPosition !== nextPosition || prevBufferedPosition !== nextBufferedPosition) {
return true;
}
return false;
}
render() { ... }
}
Most helpful comment
this.state.durationinstead.You can check out an example here