I would assume that someone would have found an easy solution to this but I haven't found a straight-forward method. I want to build a seeker bar for playing back audio through the MediaPlayer. I haven't been able to find something like an onSeekChanged listener in the MediaPlayer object so I've built an AsyncTask that just keeps refreshing through a while(playing) loop and updates the duration and bar. This doesn't seem to be the best way, however, since this while loop causes the app to run very slowly (the audio doesn't lag, but buttons like pause are delayed). So I want to know what the best implementation is for building a seeker that is efficient. This isn't a difficult question since so many apps use it, I just want to know what the proper way of doing this should be. Thanks!
First of all you need put sleep at least 1 millisecond in your cycle whit:
Thread.sleep(1);
Second you can calculate needed time for next recheck:
Thread.sleep(1000 - currentPos % 1000);
This algorithm is used in standard MediaController.
Related
I'm developing my application but i came across a problem.
When starting my app it retrieves information from database . Then It draws notes on the screen according to the information from database , it draws hi hat, snare and kick notes , if it has to be played the note is black when not it is gray.
The next step is that im using rx java to call a method called highLightNotes() .
Observable.interval(400, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Long>() { #Override
public void onNext(#NonNull Long aLong) {
highLightNotes(aLong);
}
the next step is that it is looking for black notes, and when the note is black it calls this method :
public void playSnare(){
snarePlayer.seekTo(0);
snarePlayer.start();
}
snarePlayer is a mediaplayer.
My first problem here is that it takes way too much time to hear the note. The rhytm is becoming unsteady as sometimes it takes more time to get through sometimes less.
The second problem is that im kind of rxjava noob obviously and i'm wondering why by clicking for the first time to play the rhytm it takes a couple of seconds to get it started and then it is played really fast and after that i becomes steady .
Please provide me with some more information to keep working on it , im stuck.
You're starting up a new thread the first time. See where you're telling it to subscribe on a new thread?
If you need tight control over timing like this, RxJava is NOT the way to go. You do not want a giant codebase swapping you between threads. You're just asking for pain.
I have an ExoPlayer instance initialized with 4 tracks. 2 of them are MediaCodecVideoTrackRenderer instances, each with its own ExtractorSampleSource.
I'd like to start the playback of one of those track from the middle.
I'm waiting until I get the MSG_PLAYER_STATE_READY message to be able to get the duration of the tracks and then calling seektoUs on the sample-source (also tried calling seekTo on the renderer), but both give unpredictable results.
What's the proper way to seek into a single track while the rest of the tracks play from the beginning?
Managed to solve the issue by overriding my custom TrackRenderer's doSomeWork method and calling super.doSomeWork with a custom positionUs based on the logic I needed.
Imagine score counter made with Text() entity. Simple.
After I start a game, calling setText() causes launching a GC_EXPLICIT that slows down a game causing freezes, and after a few calls - problem disappears. Firstly I thought it's a problem with Strings and concatenation in Java, so I used a StringBuilder. The problem still exists. If I change setText("$" + score + "M") to simple setText("0") no hiccups are noticed!
The problem is in Font. Creation of Texture doesn't actually load characters to this Texture! All you need to do is after creating Font simply call:
pFont.prepareLetters("0123456789".toCharArray());
with all chars you need.
Occasional hiccups that were caused by GC_EXPLICIT were happening because Font in update() was explicitly calling System.gc(). Removing this line we were back on track below the green line, yeah! 60fps.
However, the author of AndEngine might had reasons for this explicit call. Since the stages are short we granted our app call this gc() when the GameScene is paused, quit or stage complete, anywhere where there is no excessive animation.
Preparing characters upfront did not sooth the hiccups, because the texts were dynamic and we could not prepare all possible characters to keep the System.gc() in this method, but honor it later.
Indeed preparing the letters upfront does not trigger GC_EXPLICIT, as it is described in the answer provided by the OP.
EDIT:
After some research, another thing that caused < 60fps, was the SoundPool, we should have playing a sound with volume 0f,0f and looping, in order to prevent the SoundPool reset to idle state and rearm again.
I'm creating a spades app with 1 human player and 3 computer players.
The problem that I am having is, the play must happen sequentially (clockwise) and I need my program to wait on the player input. I can't use wait() and notify(). I have tried while loops to check whether the user has selected a card but those stop the program from running. I've tried recursive methods that won't return anything until the player has chosen a card. That too does not work. So what do I do? I'm stuck.
My method goes like this (leaving out the non-pertinent code)
private void game(){
while(there are more tricks to be played)
while(each player has not played){
if(human turn)
get input from player
else
computer plays
}
}
Maybe you should change a little bit your game controller. Instead of waiting for anything, have your program continuously paint the screen. If user inputs nothing, same screen is paint all the time.
Once he presses a key (or clicks a card or whatever events you have), simply modify the paint method's argument (the screen to be painted). Thus you will separate painting the screen and input handling. It's a common technique called MVC model.
Maybe this will help (it's my game creating blog, and the links inside it are also helpful):
http://m3ph1st0s.blogspot.ro/2012/12/create-games-with-libgdx-library-in.html
You don't need to adapt all your game to the game described there, only the technique of separating input from painting. As a general technique, you should NOT have input determine painting.
Hope it helps. Don't hesitate to request further help.
You can try to add Event Handlers. It will try triger a event every time the user selects a card.
Try this.
Create one thread and in that threat call sleep(1000);
I want to play one RTSP stream in a surfaceView while I prepare the other in a separate thread. However, the MediaPlayer does give an error when instantiating two SurfaceHolders:
Command PLAYER_PREPARE completed with an error or info PVMFErrResource
Despite this, the video gets buffered, but when I switch to it, only audio is played. In the Android docs it is stated that this is a consequence of not calling setDisplay(SurfaceHolder) but this is what causes the error.
Does anyone have any idea how I can make the video part of the stream show and how to avoid the error when calling setDisplay? Is this a platform limitation?
Thanks.
Maybe you could put two separate SurfaceViews inside (for example) FrameLayout. Use these with two separate MediaPlayers and show/hide (in parallel to stoping/starting video) SurfaceView you desire at given moment (using android:visibility set to GONE for example).