I have a problem seeking HLS (.m3u8) playlist on native VideoView.
I've built an Activity that when pressing on ImageView it opens up a new Activity via Intent and start playing an HLS video using native VideoView (I'm aware of the issues with HLS on Android) but when going back to Activity A after seeking in Activity B, Activity A freezes GUI for approx. 30 seconds (When pressing on UI element in Activity A, I see ANR) and then it "release" the GUI again.
Problem is when I try to use :
mVideoView.seekTo(position);
mVideoView.start()
UI in Activity B seems OK, video will not seek actually freezes and when I back pressed I get this:
LogCat:
Shutting down current MediaPlayer
System.outīš Close in OkHttp
[CDS]close[41023]
[CDS][DNS] getAllByNameImpl netId = 0
[getaddrinfo]: hostname=31.168.5.3; servname=(null); cache_mode=(null), netid=0; mark=0
[getaddrinfo]: ai_addrlen=0; ai_canonname=(null); ai_flags=4; ai_family=0
[CDS]rx timeout:60000
[socket][3] connection /31.168.5.3:8089;LocalPort=47817(0)
[CDS]connect[/31.168.5.3:8089] tm:90
ANR Key Analyze: No Key event currently.
ANR Key Analyze: Previeous Event null,finish at 1970-01-01 02:00:00.000`
And After approx. 30 seconds:
[CDS]EAGAIN in Recvfrom
[CDS]read byte is 0
surfaceDestroyed callback -, this = com.brightcove.player.view.BrightcoveSurfaceView{8b5c8c0 V.E..... ........ 0,8-1280,728}
Layout: x=0 y=8 w=1280 h=720, frame=Rect(0, 0 - 1280, 720), this = com.brightcove.player.view.BrightcoveSurfaceView{8b5c8c0 V.E..... ........ 0,8- 1280,728}
It looks as if the connection when setting Video Uri is keeping a connection open and only a timeout releases it or something like this.
It happens only on one device, Lenovo 7-inch Tablet with OS 5.0 (Lollipop), on other it does not happen.
Also, when playing regular mp4 streams I didn't encounter this problem.
Any help will be appreciated.
Related
I am using an android 4.4.4 with armv7l CPU.
For some reason, other devices with same android version but different CPUs are facing different kind of problems. My only concern is armv7l CPUs.
The Xwalk library version I am using is 23.53.589.4
I am also using NanoHTTPD to serve local files for the crosswalk webview.
Inside the oncreate
mXWalkView = new XWalkView(getApplicationContext(), (Activity) Main_activity.this);
RelativeLayout second_container = findViewById(R.id.second_container);
second_container.addView(mXWalkView);
mXWalkView.setResourceClient(new ResourceClient(mXWalkView));
XWalkPreferences.setValue(XWalkPreferences.REMOTE_DEBUGGING, false);
mXWalkView.addJavascriptInterface(new JavaScriptInterface(), "interface");
mXWalkView.clearCache(true);
mXWalkView.getSettings().setMediaPlaybackRequiresUserGesture(false);
As for the xml file I have:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
android:orientation="horizontal"
android:visibility="invisible"
tools:context=".Main_activity">
<RelativeLayout
android:id="#+id/second_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
The application displays the html file along with any images, text, iframes, etc. but for the html5 video tag it plays the video once and either doesn't loop, freezes on a certain frame or displays an empty white screen where the video should be.
When debugging the app I get the following messages which I think are connected to the problem:
E/MediaPlayer: Unable to create media player
D/MediaPlayer: create failed:
java.io.IOException: setDataSourceFD failed.: status=0x80000000
at android.media.MediaPlayer._setDataSource(Native Method)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1025)
at android.media.MediaPlayer.create(MediaPlayer.java:848)
at org.chromium.content.browser.MediaThrottler$StartWatchDogTask.doInBackground(MediaThrottler.java:107)
at org.chromium.content.browser.MediaThrottler$StartWatchDogTask.doInBackground(MediaThrottler.java:101)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
E/cr_MediaThrottler: Unable to create watch dog player, treat it as server crash.
D/cr_MediaResource: [MediaResourceGetter.java:167] resource has video
D/cr_MediaResource: [MediaResourceGetter.java:196] extracted valid metadata: MediaMetadata[durationInMilliseconds=13333, width=1280, height=720, success=true]
D/MediaPlayer: Couldn't open file on client side, trying server side
E/cr_MediaThrottler: Unable to create watch dog player, treat it as server crash.
E/MediaPlayer: Should have subtitle controller already set
These logs keep on repeating because the video is looping using javascript
As for the javascript part:
//check if the video element is stuck either at the start or at the end and attempt to reload
//if it is not stuck repeat the video from the start
if (element.currentTime == 0 || element.currentTime == element.duration) {
element.src = element.src;
element.load();
} else {
element.currentTime = 0;
}
element.play();
The HTML video is as follows:
<!-- the video source holds a link to the same video on the server -->
<video src="video2.mp4" content-type="video" transition-time="13.33" style="width: 100%; height: 100%; object-fit: fill; display: block;" id="video" autoplay muted loop playsinline>
<source src="http://example/videos/video2.mp4">
Sorry, your browser doesn't support embedded videos.
</video>
I have tried adding setMediaPlaybackRequiresUserGesture as false on the android crosswalk side but the video still didn't loop.
I have also tried adding a JavaScriptInterface to check if the video results in an error but it didn't (at least in android 4.4.4). The video played without leaving an error even when I have tried checking for the error using addEventListener()(javascript) and onerror(html).
The video is muted with autoplay and loop and this html loop doesn't work the video stops when it is done.
I have also tried loading and unloading the videos using javascript in multiple different ways but they all resulted in the same output. The videos are playing with no white screen but they still freez due to throttling. When the video freezes it doesn't go back to playing normally.
I have also added controls to the html5 video and found out that pausing and resuming using the controls causes the video to play for a few seconds before it stops again, it also allows if more than one video is present to play and then they will stop seemingly at the same time.
If one video is present, the video loops a few times (between two and four times) and then freezes, if more than one video is present, lets say two videos, they will both play once and doesn't loop. (only one of the videos is visible at a certain time, the other has a style of display none)
I have also tested on multiple 4.4.4 with armv7l CPU and still the same results.
I have a custom android AOSP ROM with a peculiar problem: The volume can only be set to either 0% or 100%. As a result, the volume buttons just turn the sound on or off. If I use the volume slider instead, and the volume is not muted, it jumps immediately to 100%. The volume is not reduced even momentarily.
Interestingly, the volume for ringtones and alarms is not affected and can be set as usual.
The problem occurs via headphones, internal speakers, and HDMI out.
I tried setprop ro.config.media_vol_steps 30, and that does work in that it changes the number of volume steps in the slider - but it does not affect the output volume. I found nothing in logcat, this is the only suspicious thing (I set the volume via slider to a low value):
02-08 06:18:43.117 1813 2298 V audio_hw_primary: out_set_parameters: routing=1024
02-08 06:18:43.670 22493 22493 I vol.Events: writeEvent touch_level_changed STREAM_MUSIC 3
02-08 06:18:44.127 22493 22493 I vol.Events: writeEvent touch_level_done STREAM_MUSIC 3
02-08 06:18:46.575 22493 22493 I vol.Events: writeEvent dismiss_dialog touch_outside
02-08 06:18:46.581 22493 24066 I vol.Events: writeEvent active_stream_changed UNKNOWN_STREAM_-1
02-08 06:18:46.695 1813 2298 V audio_hw_primary: out_set_parameters: routing=1024
02-08 06:18:49.842 1813 2298 D audio_hw_primary: out_standby
What could cause this? E.g. does the hardware report the current volume back to the UI (then it could be a driver problem)?
In your ROM, a fixed-volume (full) is set. Its a resource configuration. Usually done for HDMI devices.
I have a MusicService for MediaPlayback, wich uses a MediaPlayer with the settings:
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
and those Listeners are set:
OnPreparedListener, OnCompletionListener, OnErrorListener, OnSeekCompleteListener
The MediaPlayer is used for mp3-Playback. When one Song is finished, onCompletion is called. Then PlayNext is called, wich resets the MediaPlayer, then sets the Datasource with the URI of the next Track. Uri is loaded with:
Uri trackUri = ContentUris
.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId);
Then the Player is prepared, then the player is started. This is working fine, but only sometimes, when the Device is locked and played about 1-3 Songs while it was locked and the next Song should start, the Player doesn't prepare until i hit the power button. Figured out, that if I don't hit the PowerButton it takes the Player about 2 Minutes to prepare.
I've Logged everything now and made a few custom outputs with Log.e(...).
This is put out before prepare() (prepareAsync() delivers the same result) is called:
E/MusicService: Preparing now...
This is put out, when onPrepared is called:
E/MusicService: Player prepared.
So this is the full Device-Output after "Preparing now..." is put out:
04-02 13:54:55.506 12517-12517/at.htlleonding.musync E/MusicService: Preparing now.
04-02 13:54:55.525 811-888/? E/libsuspend: Error writing to /sys/power/state: Device or resource busy
04-02 13:54:55.544 246-14756/? D/offload_visualizer: thread exit
04-02 13:54:55.546 246-14754/? V/offload_effect_bundle: offload_effects_bundle_hal_stop_output output 1879 pcm_id 9
04-02 13:54:55.546 246-14754/? D/hardware_info: hw_info_append_hw_type : device_name = speaker
04-02 13:54:55.549 246-14752/? E/audio_hw_primary: offload_thread_loop: Compress handle is NULL
04-02 13:54:55.549 246-924/? D/audio_hw_primary: adev_close_output_stream: enter:stream_handle(0xb5bfa640)
04-02 13:54:55.549 246-924/? D/audio_hw_primary: out_standby: enter: stream (0xb5bfa640) usecase(3: compress-offload-playback)
04-02 13:54:55.555 246-924/? W/AudioFlinger: moveEffectChain_l() effect chain for session 0 not on source thread 0xb59fa000
04-02 13:54:55.611 246-15030/? I/FFmpegExtractor: android-source:0xb1834060
04-02 13:54:55.820 811-888/? E/libsuspend: Error writing to /sys/power/state: Device or resource busy
04-02 13:54:55.972 246-15030/? I/FFMPEG: [mp3 # 0xae2f4400] Skipping 0 bytes of junk at 2177007.
... Then theres no output until i hit the PowerButton. Then the Song is prepared.
If someone is interested in the full output after I hit the PowerButton until "Player prepared" is called, I created a Gist here.
Sidenote:
While the App is used, a few Album-Covers are displayed in some Fragments. They are loaded with Picasso, so I don't need to worry about memory caching. Some ImageViews are filled without Picasso (for example the ImageViews that hold the drawables of my PlayerControls). Maybe there are Problems with the memory/resources?
I might have found the answer in another thread where some faced the same problem while streaming music here.
My final solution is to use a WakeLock, wich I require before preparing a Song and release again onPrepared and onError and onDestroy of my Service. It's important to release it again to save Battery. Make sure to check if the WakeLock is held before releasing it.
I create my WakeLock like this in onCreate of my Service:
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MusicService");
aquire:
wakeLock.acquire();
release:
if(wakeLock.isHeld())
wakeLock.release();
Tested the Playback now for about 10 Minutes and didn't stop until now. I don't know if this is a very battery-saving solution
We are trying play audio from url (m3u8 file). Media player starts fine no issues. Audio also plays cleanly. Issue starts when do seek in the player. Behavior very strange. it seeks to the proper position then starts playing audio. After while it seeks again like couples seconds (better word is skips some seconds since it jumps to the position directly) and can be observed in the media playback time counter, again plays for a while again jumps some seconds and this continues till end of the media.
We have our custom seek bar which is nothing but a progressbar, and when we do seek the progress bar we send same seek position to media player by calling onseek() method.
Note: Issue Happens only Lollipop nexus devices(tablet and phone).
Strange observation jump happens only if the time counters last position 9
(i.e if mediaplayed 12:29[mm:ss] then will jump to some other random place 12:3X[mm:ss],again mediaplayed 12:39[mm:ss] then will jump to some other random place 12:4X [mm:ss] )
Why is it happening?
You should pass the outer manifest to the player. This should resolve your issue.
I try to stream (progressive e.g: http://server.com/video.mp4)
when i use the standard google mediaplayer (VideoView from android package) and register an onBufferingUpdateListener then i get the bufferpercentage that refers to the download state of the hole video. This player has also a loading view where i can see the buffer state.
This bufferpercentage and view shows me how much of the video has been downloaded.
Now when i use the Vitamio player, the onBufferingUpdateListener shows me after a few seconds 99 percent of buffering and there is no loading view too. And when i pause the playback it stops buffering immediately instead of continue buffering like the google videoview does. This is very usefull if you have a slow http stream.
Is there a way to make the vitamio-videoplayer buffer the videofiles in the same way as the google videoplayer does?
thank you
daniel
Sorry i posted that question as wrong user. Here the Answer of what i tried:
VideoView (android default - just plays few video formats) from inside the android.widget and from io.vov.vitamio.widget (vitamio - plays most video formats) package has the same structure. In both you can register an OnBufferingUdateListener that returns the bufferstate in percent:
videoview.setOnBufferingUpdateListener(new io.vov.vitamio.MediaPlayer.OnBufferingUpdateListener() {
public void onBufferingUpdate(io.vov.vitamio.MediaPlayer mp, int i) {
Log.v(TAG, "Buffer percentage done: "+i);
}
});
or with the android default VideoView:
videoview.setOnBufferingUpdateListener(new android.media.MediaPlayer.OnBufferingUpdateListener() {
public void onBufferingUpdate(android.media.MediaPlayer mp, int i) {
Log.v(TAG, "Buffer percentage done: "+i);
}
});
If i use android.widget.VideoView the buffer percentage slowly increases until it reaches 100% - The video file has been downloaded completely. And it continues updating BufferingUpdate when i press the pause button.
When i use io.vov.vitamio.widget.VideoView the percentage reaches 100% within seconds. Then the video starts and the OnBufferingUpdateListener never gets called again (when i call getBufferPercentage it is always at 99 percent. That seems to be the reason). And as i sayed: It seems to stop buffering when i press the pause button.
I think the buffering works different in vitamio. But that's crap. Especially when i stream videos from the web and the video datarate is higher than the download speed i need to prebuffer the video by pressing pause and wait until it has downloaded enough data to watch it smoothly. Hope you got what i mean. thank you