- Android Studio: запуск и остановка звука с помощью mediaPlayer
- 4 ответа
- MediaPlayer: Simplified Video Playback on Android
- Version
- Getting Started
- Understanding the code
- MediaPlayer
- Playing Video From Local Resources
- MediaPlayer is prepared
- Improving the UX
- Interacting with the SeekBar
- Playing Video from the Gallery
- Playing the video after it has been downloaded
- Releasing the Resources
- Executing Asynchronously
- Streaming a Video From a URL
- Digital Right Management
- DRM MediaPlayer
- Where To Go From Here?
Android Studio: запуск и остановка звука с помощью mediaPlayer
Как start и stop воспроизводить музыку, используя одну и ту же кнопку. Приведенный ниже код будет воспроизводить песню несколько раз (с перекрытием), если я нажму на нее несколько раз.
И еще одна проблема — куда вставить функции starTimer и StopTimer , чтобы starTimer был активен, если звук не воспроизводится, и stopTimer будет активен, если звук воспроизводится.
И для функции startTimer stopTimer
4 ответа
Пожалуйста, укажите ниже код в Global:
Теперь в onCreate методе:
Кнопка паузы воспроизведения:
Когда аудио готово к воспроизведению:
Аудио завершено, затем автоматическая остановка:
Не забудьте добавить эту строку:
Чтобы остановить музыку / звук с помощью медиаплеера, создайте логическое значение isPlaying . сделать это правдой, когда музыка играет
Объявите isPlaying как глобальную переменную как
Теперь вы можете создать метод, который будет проверять значение isPlaying и воспроизводить или приостанавливать музыку, вызывая этот метод onClick() кнопки
Надеюсь, это поможет!
Приведенный ниже код будет воспроизводить песню несколько раз (с перекрытием), если я нажму на нее несколько раз.
Поскольку каждый раз, когда вы нажимаете кнопку, вы создаете экземпляр объекта медиаплеера, чтобы решить эту проблему, сделайте свой объект проигрывателя medica полем класса, а не локальным полем метода, и сначала проверьте, не является ли объект нулевым, прежде чем создавать его.
И не нужно иметь переменную, чтобы проверить, воспроизводится ли медиа, так как вы можете проверить это непосредственно из объекта медиаплеера.
Так что измени свой код на
Что касается вопроса с таймером, не очень понятно, как вы используете свой таймер?
Лучше сделать одно логическое значение при нажатии кнопки, а затем легко обрабатывать
IsClick имеет значение false, означает, что если будет выполнено другое действие. В противном случае вы делаете остановку медиаплеера и функцию остановки таймера.
Источник
MediaPlayer: Simplified Video Playback on Android
Playing videos is a common requirement in Android apps. In this tutorial learn about handling video playback via the MediaPlayer API on Android.
Version
- Kotlin 1.4, Android 4.4, Android Studio 4.0
Playing audio or video in Android apps is a common requirement for many projects. Many apps in the Google Play Store, even some non-streaming ones, provide audio and video playback. Above all, it’s an important topic that will lead you to many job opportunities.
In this tutorial, you’ll build an Android app that plays video from various sources, such as videos locally stored in your phone, the res folder, gallery and a URL using MediaPlayer .
Along the way you’ll learn about:
- MediaPlayer.
- The states of MediaPlayer.
- Playing video from the res/raw folder.
- Playing video from a URL.
- Best practices for MediaPlayer.
- Digital Right Management.
Getting Started
Download the materials using the Download Materials button at the top or the bottom of this page. Extract and open the starter project in Android Studio.
Build and run. You’ll see something like this:
The app isn’t interactive yet because the starter project only consists of UI and some basic code. You’ll implement the functionality throughout this tutorial.
Understanding the code
Before the hands-on part of this tutorial, take some time to understand the codebase you’ll build on. Navigate to these three files and check out their contents:
- AndroidManifest.xml: At the top of the manifest file you’ll find android.permission.INTERNET . In this tutorial, you’ll play a video from a URL, so you’ll need the INTERNET permission.
- activity_video.xml: This is the one and only layout file in the project. It consists of:
- A VideoView to play video.
- A ProgressBar to shows the user it’s loading a video.
- Two TextViews and a SeekBar to show progress.
- An ImageButton to play and pause a video.
- VideoActivity.kt: This might look a bit overwhelming, but if you skim through and read the comments, you’ll find it quite simple.
The class implements a few interface classes to manage MediaPlayer and seekBar callbacks. You’ll understand these implementations once you start working on the functionality.
Also, to keep your app from falling asleep, you’ll need to keep your screen on. Notice this line inside onCreate() which adds a flag window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) . Setting this flag ensures your screen stays on, while the app is in use. You don’t want the user’s device to fall asleep and lock while they’re watching a video on your app, do you?
MediaPlayer
MediaPlayer is a part of the Android multimedia framework that plays audio or video from the resource directory and gallery. It also streams music or video from a URL.
When a media file plays, the MediaPlayer API goes through several states, which are summarized in the diagram below:
That’s a lot of information to take in, but before you can use the MediaPlayer API efficiently, you need to understand these states, so let’s take a look at each of them.
- Idle State: MediaPlayer is in an idle state when you first instantiate it, or first create it using the new keyword. You also reach this state after you call reset() .
At this stage, you can’t play, pause or stop the media. If you try to force it, the app might crash.
Okay, enough theory. It’s time to code!
Playing Video From Local Resources
You will start with playing a video file in the raw directory. There’s a video in the starter project named test_video.mp4.
From the states you learned above, you may see that to play the video in your VideoView , you have to:
- Set the data source using MediaPlayer
- Call the start() function
But you may be wondering where do you add this code? For this, a couple of options may come to your mind.
The most common way to add new code into Android apps is to put it in the onCreate() method, because you know it will be the entry point of your activity. But in the case of Media Player that’s not good practice for two reasons:
- First, you don’t know the size of the video or how much time MediaPlayer will take to load it.
- Second, MediaPlayer can play a video in VideoView through its surface, which also takes time.
Take a look at the code inside the onCreate() method of VideoActivity. In there you will see the following line: video_view.holder.addCallback(this) , this gets a callback when the VideoView ‘s surface is ready for playing video. When this surface is ready, it calls surfaceCreated() .
Next, inside surfaceCreated() replace // TODO (1) with:
In this code, you perform three tasks:
- First, you pass the location, URI, of the video.
- Then, you set MediaPlayer ‘s display to the VideoView ‘s surface by calling setDisplay(surfaceHolder) .
MediaPlayer is prepared
When MediaPlayer is prepared, it invokes onPrepared() . This is the point where you will start playing the video.
To do that, replace // TODO (2) inside onPrepared() with:
- Make the progressBar invisible.
- Tell MediaPlayer to start the video.
Now Build and Run.
Tada! Now you can play the video from your raw or resource directory, but still, something is missing. The seekBar isn’t updating, and you can’t pause or play the video.
Next, you’ll implement the missing functionality and make the app more intuitive.
Improving the UX
Before you add the functionality to play, pause or fast-forward video using SeekBar, you need to create a few functions and extension properties.
At the bottom of VideoActivity.kt replace // TODO (3) with:
These extension properties help you implement those functionalities. MediaPlayer itself provides you with the video duration and currentPosition, therefore you don’t have to worry for tracking them.
- seconds returns the total duration of the video in seconds.
- currentSeconds returns the current playback position in seconds of the video.
Next, convert the seconds to a more readable format by replacing // TODO (4) with:
In this function you convert seconds to MM:SS format. If the video is more than 60 seconds long, it’s better to show 2:32 minutes rather than 152 seconds.
In adition, you’ll create three functions that initialize and periodically update seekbar and convert the seconds to a more readable format.
To initialize seekbar , replace // TODO (5) with:
When MediaPlayer prepares to play the video this function is executed. The code performs the following:
- Sets the maximum value for SeekBar
- Sets default values for TextViews which shows the progress and the total duration of the video.
- Hides the ProgressBar .
- Enables the play button .
Next, to periodically update the seekbar as the video plays, replace // TODO (6) with:
In this function, you use Runnable to execute the code periodically after every one second. Runnable is a Java interface and executes on a separate thread. Since it executes on a separate thread, it won’t block your UI and the SeekBar and TextViews will update periodically.
Instead of playing the video when MediaPlayer is ready, it would be better if the user could play and pause the video by using the imageButton .
Inside the onCreate() function replace // TODO (7) with:
- Check if MediaPlayer is playing any video.
- If it is, you pause the video and change the button icon to play.
- If not, you play the video and change the button icon to pause.
Next, replace all the code added to the onPrepared() ‘s body with a call to initalizeSeekBar() and updateSeekBar() which you created earlier:
Now your app is more intuitive.
Build and Run. You can play or pause the video and see the progress on seekBar and TextView .
Interacting with the SeekBar
Now the app is more intuitive for the user, except for the SeekBar . Even though the SeekBar updates with time, you can’t fast-forward or rewind the video by tapping or dragging it.
For that, you’ll use the onProgressChanged() method of SeekBar . Whenever there’s a change in the SeekBar ‘s progress, it will invoke this function.
The SeekBar change listener is already in the code, so navigate to onProgressChanged() and replace // TODO (8) with:
The function onProgressChanged() has three parameters:
- seekBar: Instance of the seekBar .
- progress: Progress of seekBar in seconds.
- fromUser: Boolean which tells you if the change is because of user interaction. If the change in progress is due to user interaction, it’ll be true. If not, it’ll be false.
You use this parameter to update MediaPlayer ‘s progress if the seekbar ‘s progress level is manually changed.
Now your user can fast-forward or rewind the video using seekBar . Build and run to give it a try. :]
Playing Video from the Gallery
The app works great now, but it would be better if users could select a video from their gallery and play it. You’ll implement that next.
The options button in the toolbar and its functionality are already in the starter project.
Before you add new code, you need to understand what’s happening in the existing code. When the user selects an option the app invokes onOptionItemSelected() with the menuItem as a parameter.
Now, inside the when statement replace // TODO (9) with:
Here you use an intent to get the URI for the file the user selected from the gallery. In the code:
- You get an Intent which is a messaging object in Android used to request different action types.
- You ensure that the intent type is a video format.
- Then you specify this is an Intent with an action of GET content type.
- Finally, you trigger the intent waiting for a result.
Playing the video after it has been downloaded
Once the activity returns something from the intent, startActivityForResult() invokes onActivityResult() , which passes GET_VIDEO as a request_code .
Inside the startActivityForResult() function replace // TODO (10) with:
- Check the resultCode . If the operation was executed successfully, it returns Activity.RESULT_OK .
- Check the requestCode to identify the caller and define if the requestCode was actually a video.
- Assign URI to the selectedVideoUri variable you declared earlier.
- Invoke surfaceCreated() by calling video_view.holder.addCallback(this) .
It will probably ask you to import Activity, so add it at the top with your other inputs with:
Next, update setDataSource() so you pass the correct URI in the parameter. Navigate to surfaceCreated() and replace the function body with:
Voila! Now your user can open the gallery, select a video and play it in your app. Build and run to see how it works now.
Releasing the Resources
MediaPlayer API consumes a lot of resources. So, you should always release those resources by calling release() .
As per the official Android documentation, you should release the resources whenever your app is in background or stopped state. Failing to could lead to continuous battery consumption for the device and playback failure for other apps if multiple instances of the same codec aren’t supported. It could also degrade the device’s performance in general.
In onDestroy() , replace // TODO (11) with:
Here you remove the runnable from the thread or message queue by calling removeCallbacks() . If you didn’t, your runnable would keep executing in the background.
Build and Run. It looks like nothing changed, but you ensured the resources release when the user kills the app.
Executing Asynchronously
Asynchronous code is very important for Android apps. You may have not noticed, but currently, you are loading the video asynchronously.
In most cases, videos are heavy and take time to load, therefore, you need to make the code asynchronous. When that happens, MediaPlayer will lead the app to ANR, or Application Not Responding, state. In short, your app will become non-responsive and crash.
To load the media file asynchronously what you did was using prepareAsync() instead of prepare() inside the surfaceCreated() function. In other words, if you try to use prepare() in that line and run the app, it will be there loading for a long time.
Seriously, that’s it! That’s all you had to do.
Next, you’ll implement asynchronously streaming a video from a URL.
Streaming a Video From a URL
Fortunately, you don’t have to make many changes to prepare MediaPlayer asynchronously and stream a video from a URL.
In surfaceCreated() , replace setDataSource() with:
Then, in surfaceCreated() replace prepare() with prepareAsync() .
After you make those changes, surfaceCreated() will look like this:
Nice! Now your MyTube app can play videos from res directory, gallery and even stream a video from a URL.
Before you finish, there’s one more topic you need to explore: DRM, or Digital Right Management.
Digital Right Management
DRM, or Digital Right Management, technologies are a set of tools that protect or encrypt video and audio files. There are many technologies to help with that, such as Microsoft’s PlayReady and Google’s Widevine. Working with DRM-protected files is a topic worthy of it’s own tutorial.
MediaPlayer added support to play DRM protected videos in Android 8 with API 26. If you want to play a DRM protected video, either you have to set your app’s minSdkVersion to 26, or annotate your class with @RequiresApi(Build.VERSION_CODES.O).
DRM MediaPlayer
Because DRM mostly relies on the security-by-obscurity principle, it’s hard to get your hands on any DRM protected media files. You won’t play a DRM protected file as it’s too complicated for this tutorial. Instead, you’ll see an overview of the changes you have to make to play a DRM protected file.
Take a look at onCreate() again. You’ll see this:
This line of code tells MediaPlayer it could be accessing a DRM protected file. You don’t have to worry about the app crashing if the media file is not DRM protected: It takes care of that itself. If the media file is DRM protected the app invokes onDrmInfo() .
After that, inside onDrmInfo() replace // TODO (12) with :
- Fetch the UUID, or key, of the DRM scheme in use. There are several types of DRM protection schemes. Examine the map of UUIDs in drmInfo?.supportedSchemes?.get(0) and retrieve the supported schemes. Schemes supported depend mainly on the device and OEM, if you ever get a DRM, you will need to dive deeper on this topic.
- Pass this retrieved key to prepareDrm() to prepare the DRM.
- Get the decrypt key from the licensed server using getKeyRequest() .
- Then provide the key response from the license server to the DRM engine plugin using provideKeyResponse() .
Android Studio will most likely ask you to import the DRM library, so add the following line to the top of your file with your other imports:
This code is only for demonstration purposes. Because of this, it won’t affect the app since you don’t have access to any DRM protected files.
If you ever have to work with a DRM protected media file, a better alternative would be using ExoPlayer because it provides more functionalities.
Where To Go From Here?
Congratulations on your first MediaPlayer app! You can download the final project using the Download Materials button at the top or bottom of this tutorial.
In this tutorial, you covered some basics of MediaPlayer like:
- Understanding MediaPlayer and its states.
- Playing video from the res/raw folder.
- Playing video from a URL.
- Async Programming.
- Best practices for media player.
- Digital Right Management.
While you covered a lot in this tutorial, there’s still more to learn. For a next step, explore ExoPlayer. Google created ExoPlayer, a library that lets you take advantage of features not yet supported by MediaPlayer API, such as DASH and SmoothStreaming. To learn more about ExoPlayer check out our ExoPlayer tutorial.
I hope you enjoyed this tutorial. If you have any questions or comments, please join the discussion below. :]
Источник