4package org.qtproject.qt.android.multimedia;
6import java.io.IOException;
7import java.lang.String;
8import java.util.HashMap;
9import java.io.FileInputStream;
13import android.media.MediaPlayer;
14import android.media.MediaFormat;
15import android.media.PlaybackParams;
16import android.media.AudioAttributes;
20import java.io.FileDescriptor;
21import android.content.res.AssetFileDescriptor;
22import android.content.res.AssetManager;
23import android.view.SurfaceHolder;
25import java.util.concurrent.Executors;
26import java.util.concurrent.ScheduledExecutorService;
27import java.util.concurrent.ScheduledFuture;
28import java.util.concurrent.TimeUnit;
30class QtAndroidMediaPlayer
44 private MediaPlayer mMediaPlayer =
null;
45 private AudioAttributes mAudioAttributes =
null;
46 private HashMap<String, String> mHeaders =
null;
47 private Uri mUri =
null;
48 private final long mID;
50 private boolean mMuted =
false;
51 private int mVolume = 100;
52 private static final String TAG =
"Qt MediaPlayer";
53 private SurfaceHolder mSurfaceHolder =
null;
54 private ScheduledExecutorService mProgressScheduler =
null;
55 private ScheduledFuture<?> mProgressWatcherHandle =
null;
59 final static int Idle = 0x2;
60 final static int Preparing = 0x4;
61 final static int Prepared = 0x8;
63 final static int Started = 0x20;
64 final static int Stopped = 0x40;
65 final static int Paused = 0x80;
66 final static int PlaybackCompleted = 0x100;
67 final static int Error = 0x200;
82 int getType() {
return this.type; }
83 String getMime() {
return this.mime; }
84 String getLanguage() {
return this.language; }
87 private volatile int mState =
State.Uninitialized;
92 private class MediaPlayerErrorListener
93 implements MediaPlayer.OnErrorListener
96 public boolean onError(
final MediaPlayer mp,
100 setState(
State.Error);
109 private class MediaPlayerBufferingListener
110 implements MediaPlayer.OnBufferingUpdateListener
112 private int mBufferPercent = -1;
114 public void onBufferingUpdate(
final android.media.MediaPlayer mp,
119 if (mBufferPercent == percent)
130 private class MediaPlayerCompletionListener
131 implements MediaPlayer.OnCompletionListener
134 public void onCompletion(
final MediaPlayer mp)
136 setState(
State.PlaybackCompleted);
144 private class MediaPlayerInfoListener
145 implements MediaPlayer.OnInfoListener
148 public boolean onInfo(
final MediaPlayer mp,
161 private class MediaPlayerPreparedListener
162 implements MediaPlayer.OnPreparedListener
166 public void onPrepared(
final MediaPlayer mp)
168 setState(
State.Prepared);
178 private class MediaPlayerSeekCompleteListener
179 implements MediaPlayer.OnSeekCompleteListener
183 public void onSeekComplete(
final MediaPlayer mp)
193 private class MediaPlayerVideoSizeChangedListener
194 implements MediaPlayer.OnVideoSizeChangedListener
198 public void onVideoSizeChanged(
final MediaPlayer mp,
207 private class MediaPlayerTimedTextListener
implements MediaPlayer.OnTimedTextListener
210 public void onTimedText(MediaPlayer mp, TimedText text)
222 MediaPlayer getMediaPlayerHandle()
227 private void setState(
int state)
239 if (mMediaPlayer !=
null)
242 mMediaPlayer =
new MediaPlayer();
243 setState(
State.Idle);
245 setVolumeHelper(mMuted ? 0 : mVolume);
246 setAudioAttributes(mMediaPlayer, mAudioAttributes);
248 mMediaPlayer.setOnBufferingUpdateListener(
new MediaPlayerBufferingListener());
249 mMediaPlayer.setOnCompletionListener(
new MediaPlayerCompletionListener());
250 mMediaPlayer.setOnInfoListener(
new MediaPlayerInfoListener());
251 mMediaPlayer.setOnSeekCompleteListener(
new MediaPlayerSeekCompleteListener());
252 mMediaPlayer.setOnVideoSizeChangedListener(
new MediaPlayerVideoSizeChangedListener());
253 mMediaPlayer.setOnErrorListener(
new MediaPlayerErrorListener());
254 mMediaPlayer.setOnPreparedListener(
new MediaPlayerPreparedListener());
255 mMediaPlayer.setOnTimedTextListener(
new MediaPlayerTimedTextListener());
257 mProgressScheduler = Executors.newScheduledThreadPool(1);
260 void startProgressWatcher()
263 if (mProgressScheduler.isTerminated() || mProgressScheduler ==
null)
264 mProgressScheduler = Executors.newScheduledThreadPool(1);
266 mProgressWatcherHandle = mProgressScheduler.scheduleAtFixedRate(
new Runnable() {
272 }, 10, 100, TimeUnit.MILLISECONDS);
275 void cancelProgressWatcher()
277 if (mProgressScheduler !=
null)
278 mProgressScheduler.shutdown();
283 if ((mState & (
State.Prepared
286 |
State.PlaybackCompleted)) == 0) {
291 mMediaPlayer.start();
292 setState(
State.Started);
293 startProgressWatcher();
294 }
catch (
final IllegalStateException exception) {
301 if ((mState & (
State.Started |
State.Paused |
State.PlaybackCompleted)) == 0)
305 mMediaPlayer.pause();
306 setState(
State.Paused);
307 }
catch (
final IllegalStateException exception) {
315 if ((mState & (
State.Prepared
319 |
State.PlaybackCompleted)) == 0) {
325 setState(
State.Stopped);
326 cancelProgressWatcher();
327 }
catch (
final IllegalStateException exception) {
333 void seekTo(
final int msec)
335 if ((mState & (
State.Prepared
338 |
State.PlaybackCompleted)) == 0) {
343 if (
android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.O) {
346 mMediaPlayer.seekTo(msec, MediaPlayer.SEEK_CLOSEST);
348 mMediaPlayer.seekTo(msec);
350 }
catch (
final IllegalStateException exception) {
357 boolean playing =
false;
358 if ((mState & (
State.Idle
364 |
State.PlaybackCompleted)) == 0) {
369 playing = mMediaPlayer.isPlaying();
370 }
catch (
final IllegalStateException exception) {
379 if ((mState & (
State.Initialized |
State.Stopped)) == 0)
383 mMediaPlayer.prepareAsync();
384 setState(
State.Preparing);
385 }
catch (
final IllegalStateException exception) {
392 mHeaders =
new HashMap<String, String>();
402 if (mState ==
State.Uninitialized)
405 if (mState !=
State.Idle)
409 if (mState !=
State.Idle) {
410 Log.w(
TAG,
"Trying to set data source of a media player that is not idle!");
414 if (mSurfaceHolder !=
null)
415 mMediaPlayer.setDisplay(mSurfaceHolder);
417 AssetFileDescriptor afd =
null;
418 FileInputStream fis =
null;
420 mUri = Uri.parse(
path);
421 if (mUri.getScheme().compareTo(
"assets") == 0) {
422 final String asset = mUri.getPath().substring(1 );
423 final AssetManager am = mContext.getAssets();
424 afd = am.openFd(asset);
425 final long offset = afd.getStartOffset();
426 final long length = afd.getLength();
429 }
else if (mUri.getScheme().compareTo(
"file") == 0) {
430 fis =
new FileInputStream(mUri.getPath());
432 mMediaPlayer.setDataSource(
fd);
433 }
else if (mUri.getScheme().compareTo(
"content") == 0) {
434 mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
436 mMediaPlayer.setDataSource(
path);
438 setState(
State.Initialized);
439 }
catch (
final Exception exception) {
447 }
catch (
final IOException ioe) { }
449 if ((mState &
State.Initialized) == 0) {
450 setState(
State.Error);
459 private boolean isMediaPlayerPrepared()
461 int preparedState = (State.Prepared | State.Started | State.Paused | State.Stopped
462 |
State.PlaybackCompleted);
463 return ((mState & preparedState) != 0);
466 TrackInfo[] getAllTrackInfo()
468 if (!isMediaPlayerPrepared()) {
469 Log.w(
TAG,
"Trying to get track info of a media player that is not prepared!");
470 return new TrackInfo[0];
473 MediaPlayer.TrackInfo[] tracks =
new MediaPlayer.TrackInfo[0];
477 tracks = mMediaPlayer.getTrackInfo();
478 }
catch (
final IllegalStateException exception) {
482 int numberOfTracks = tracks.length;
483 TrackInfo[] qtTracksInfo =
new TrackInfo[numberOfTracks];
487 MediaPlayer.TrackInfo track = tracks[
index];
489 int type = track.getTrackType();
499 private String getMimeType(MediaPlayer.TrackInfo trackInfo)
503 String defaultMimeType =
"application/octet-stream";
507 MediaFormat mediaFormat = trackInfo.getFormat();
508 if (mediaFormat !=
null) {
509 mimeType = mediaFormat.getString(MediaFormat.KEY_MIME, defaultMimeType);
515 void selectTrack(
int index)
517 if (!isMediaPlayerPrepared()) {
518 Log.d(
TAG,
"Trying to select a track of a media player that is not prepared!");
523 mMediaPlayer.selectTrack(
index);
524 }
catch (
final IllegalStateException exception) {
529 void deselectTrack(
int index)
531 if (!isMediaPlayerPrepared()) {
532 Log.d(
TAG,
"Trying to deselect track of a media player that is not prepared!");
538 mMediaPlayer.deselectTrack(
index);
539 }
catch (
final IllegalStateException exception) {
544 int getSelectedTrack(
int type)
547 int InvalidTrack = -1;
548 if (!isMediaPlayerPrepared()) {
549 Log.d(
TAG,
"Trying to get the selected track of a media player that is not prepared!");
553 boolean isVideoTrackType = (
type == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO);
554 boolean isAudioTrackType = (
type == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO);
555 boolean isTimedTextTrackType = (
type == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT);
556 boolean isSubtitleTrackType = (
type == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE);
558 if (!(isVideoTrackType || isAudioTrackType || isSubtitleTrackType
559 || isTimedTextTrackType)) {
561 "Trying to get a selected track of a invalid type"
562 +
" Only Video,Audio, TimedText and Subtitle tracks are selectable.");
567 return mMediaPlayer.getSelectedTrack(
type);
568 }
catch (
final IllegalStateException exception) {
575 int getCurrentPosition()
577 int currentPosition = 0;
578 if ((mState & (
State.Idle
584 |
State.PlaybackCompleted)) == 0) {
585 return currentPosition;
589 currentPosition = mMediaPlayer.getCurrentPosition();
590 }
catch (
final IllegalStateException exception) {
594 return currentPosition;
601 if ((mState & (
State.Prepared
605 |
State.PlaybackCompleted)) == 0) {
610 duration = mMediaPlayer.getDuration();
611 }
catch (
final IllegalStateException exception) {
618 void setVolume(
int volume)
629 setVolumeHelper(mVolume);
632 private void setVolumeHelper(
int volume)
634 if ((mState & (
State.Idle
640 |
State.PlaybackCompleted)) == 0) {
645 float newVolume = (float)volume / 100;
646 mMediaPlayer.setVolume(newVolume, newVolume);
647 }
catch (
final IllegalStateException exception) {
654 return mSurfaceHolder;
657 void setDisplay(SurfaceHolder sh)
661 if ((mState &
State.Uninitialized) != 0)
664 mMediaPlayer.setDisplay(mSurfaceHolder);
673 void mute(
final boolean mute)
676 setVolumeHelper(mute ? 0 : mVolume);
686 if (mState ==
State.Uninitialized) {
690 mMediaPlayer.reset();
691 setState(
State.Idle);
692 cancelProgressWatcher();
697 if (mMediaPlayer !=
null) {
698 mMediaPlayer.reset();
699 mMediaPlayer.release();
703 setState(
State.Uninitialized);
704 cancelProgressWatcher();
707 void setAudioAttributes(
int type,
int usage)
709 mAudioAttributes =
new AudioAttributes.Builder()
711 .setContentType(
type)
714 setAudioAttributes(mMediaPlayer, mAudioAttributes);
717 static private void setAudioAttributes(MediaPlayer
player, AudioAttributes attr)
719 if (
player ==
null || attr ==
null)
723 player.setAudioAttributes(attr);
724 }
catch (
final IllegalArgumentException exception) {
729 boolean setPlaybackRate(
float rate)
731 PlaybackParams playbackParams = mMediaPlayer.getPlaybackParams();
732 playbackParams.setSpeed(
rate);
736 playbackParams.setPitch(Math.abs(
rate));
739 mMediaPlayer.setPlaybackParams(playbackParams);
740 }
catch (IllegalStateException | IllegalArgumentException e) {
741 Log.e(
TAG,
"Cannot set playback rate " +
rate +
" :" + e.toString());
745 if ((mState &
State.Started) == 0 && mMediaPlayer.isPlaying()) {
746 setState(
State.Started);
747 startProgressWatcher();
static const QString context()
struct wl_display * display
static QString header(const QString &name)
EGLOutputLayerEXT EGLint EGLAttrib value
[3]
constexpr int Uninitialized
GLenum GLuint GLenum GLsizei length
GLenum GLuint GLintptr offset
GLsizei const GLchar *const * path
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
textPart setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"text\""))