Music-Player
Fully functional music player which is written in swift programming language
I'm using a socket as a proxy to the MediaPlayer so I can download and decrypt mp3 audio before writing it to the socket. This is similar to the example shown in the NPR news app however I'm using this for all Android version 2.1 - 4 atm.
NPR StreamProxy code - http://code.google.com/p/npr-android-app/source/browse/Npr/src/org/npr/android/news/StreamProxy.java
My issue is that playback is fast for 2.1 - 2.3, but in Android 4.0 ICS the MediaPlayer buffers too much data before firing the onPrepared listener.
An example amount of data written to the Socket OutputStream before onPrepared():
On SGS2 with 2.3.4 - onPrepared() after ~ 133920 bytes
On Nexus S with 4.0.4 - onPrepared() after ~ 961930 bytes
This also occurs on the Galaxy Nexus.
Weirdly the 4.0 emulator doesn't buffer as much data as 4.0 devices. Anyone experience a similar issue with the MediaPlayer on ICS?
EDIT
Here's how the proxy is writing to the socket. In this example it's from a CipherInputStream loaded from a file, but the same occurs when it's loaded from the HttpResponse.
final Socket client = (setup above)
// encrypted file input stream
final CipherInputStream inputStream = getInputStream(file);
// setup the socket output stream
final OutputStream output = client.getOutputStream();
// Writing the header
final String httpHeader = buildHttpHeader(file.length());
final byte[] buffer = httpHeader.getBytes("UTF-8");
output.write(buffer, 0, buffer.length);
int writtenBytes = 0;
int readBytes;
final byte[] buff = new byte[1024 * 12]; // 12 KB
while (mIsRunning && (readBytes = inputStream.read(buff)) != -1) {
output.write(buff, 0, readBytes);
writtenBytes += readBytes;
}
output.flush();
output.close();
The HTTP Headers that are written to the MediaPlayer before the audio..
private String buildHttpHeader(final int contentLength) {
final StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.1 200 OK\r\n");
sb.append("Content-Length: ").append(contentLength).append("\r\n");
sb.append("Accept-Ranges: bytes\r\n" );
sb.append("Content-Type: audio/mpeg\r\n");
sb.append("Connection: close\r\n" );
sb.append("\r\n");
return sb.toString();
}
I've looked around for alternate implementations but as I have encrypted audio and the MediaPlayer does not support InputStreams as a data source my only option (I think..) is to use a proxy such as this.
Again, this is working fairly well Android 2.1 - 2.3 but in ICS the MediaPlayer is buffering a huge amount of this data before playing.
EDIT 2 :
Further testing is showing that this is also an issue on the SGS2 once upgraded to Android 4.0.3. So it seems like the MediaPlayer's buffering implementation has changed significantly in 4.0. This is frustrating as the API provides no way to alter the behaviour.
EDIT 3 :
Android bug created. Please add comments and star there as well
http://code.google.com/p/android/issues/detail?id=29870
EDIT 4 :
My playback code is fairly standard.. I have the start() call on the MediaPlayer in my onPrepared() method.
mCurrentPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mCurrentPlayer.setDataSource(url);
mCurrentPlayer.prepareAsync();
Have tried it using just prepare() and also ajacian81's recommended way but to no avail.
I should add that recently a Google employee got back to me about my question and confirmed that the buffer size was intentionally increased in ICS (for HD content). It has been requested to the API developers to add the ability to set a buffer size on MediaPlayer.
Though I think this API change request had been around before I came along so I wouldn't advise anyone to hold their breath.
Source: (StackOverflow)
I'm trying to access media files (music) on the users device to play them; an easy "hello world"-music player app.
I've followed some tutorials and they basically give the same code. But it won't work; it keeps crashing and telling me:
error.....
Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media from pid=27696, uid=10059 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
....
Now, this is my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="slimsimapps.troff" >
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
This is my Java-method:
public void initialize() {
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor == null) {
// query failed, handle error.
} else if (!cursor.moveToFirst()) {
// no media on the device
} else {
do {
addSongToXML(cursor);
} while (cursor.moveToNext());
}
}
I have tried:
To put this at different places in the manifest file:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE”/>
To add android:maxSdkVersion at Read external storage premission:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="21" />
To put this in the manifest / application / activity-tag:
android:exported=“true”
To put grantUriPremission between uri and cursro in the javamethod:
grantUriPermission(null, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
To use this, it won't crash, but the cursor becomes null:
uri = MediaStore.Audio.Media.getContentUri("EXTERNAL_CONTENT_URI”);
To use INTERNAL content uri, this works as expected, but it only gives "OS-sounds" such as shutter-sound, low-battery-sound, button-click and such:
uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
Pleas help, this should not be a hard problem i know, but i feel like such a beginner!
I have read and tried (or considered them to be not applicable for my problem):
Stack trace:
09-08 06:59:36.619 2009-2009/slimsimapps.troff D/AndroidRuntime﹕ Shutting down VM
--------- beginning of crash
09-08 06:59:36.619 2009-2009/slimsimapps.troff E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: slimsimapps.troff, PID: 2009
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.view.View$DeclaredOnClickListener.onClick(View.java:4452)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media from pid=2009, uid=10059 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:1599)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:421)
at android.content.ContentResolver.query(ContentResolver.java:491)
at android.content.ContentResolver.query(ContentResolver.java:434)
at slimsimapps.troff.MainActivity.initialize(MainActivity.java:106)
at slimsimapps.troff.MainActivity.InitializeExternal(MainActivity.java:80)
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4447)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
--------- beginning of system
Source: (StackOverflow)
I want to develop a preset equalizer(not graphical) and set like a classical,jazz,normal,rock(these are represented in spinner). Can anbody help me regarding this.
Source: (StackOverflow)
I have developing the application to fetching data from sd card.
I used this option for filtering but when I used logcat I found that I only get data of only file sdcard/some_dir
But I have sound files into different folder so if possible give me universal code to fetch all the mp3 file form the sdcard.
class FileExtensionFilter implements FilenameFilter {
public boolean accept(File dir, String name) {
return (name.endsWith(".mp3") || name.endsWith(".MP3"));
}
}
Source: (StackOverflow)
I am trying to receive information about the currently played track in a iOS app. This works pretty fine while the iPhone is not connected to an accessory. If I connect it to my car (Opel Astra, iPhone jack), the following code stops to work as described in the documentation:
If you create an iPod music player and the user plays an item from another library using Home Sharing, the value of this property is nil
.
Code:
// nil while connected to an accessory
MPMediaItem *nowPlayingMediaItem =
[[MPMusicPlayerController iPodMusicPlayer] nowPlayingItem];
// Works while not connected to an accessory
NSString *title = [nowPlayingMediaItem valueForProperty:MPMediaItemPropertyTitle];
I even tried "hacky" stuff like to access "private" properties (original code):
MPMediaQuery *query=nil;
MPMediaItemCollection *collection=nil;
id internalPlayer=nil;
Ivar internalPlayeriVar = object_getInstanceVariable(iPod, "_internal", NULL);
internalPlayer = object_getIvar(iPod, internalPlayeriVar);
NSLog(@"internalPlayer: %@", internalPlayer);
Ivar queryIvar = object_getInstanceVariable(internalPlayer, "_query", NULL);
query = object_getIvar(internalPlayer, queryIvar); // nil everytime
Ivar collectionIvar = object_getInstanceVariable(internalPlayer,
"_itemCollection", NULL);
collection = object_getIvar(internalPlayer, collectionIvar); // nil everytime
or to call private methods:
// Same behaviour like [iPod nowPlayingItem], works
// only while no accessory is connected
MPMediaItem *nowPlayingMediaItem =
[iPod nowPlayingItemAtIndex:[iPod indexOfNowPlayingItem]];
// Works while not connected to an accessory
NSString *title = [nowPlayingMediaItem valueForProperty:MPMediaItemPropertyTitle];
Its also no solution to access the new MPNowPlayingInfoCenter
, its nil
all the time.
[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo
My car plays my music directly without using a iPhone app and it seems my iPhone knows what the car is currently playing because it displays the title, artist and cover icon on the lock screen (and only there). Also the internal play count gets increased.
If I check the playback state, it returns also YES
if the car plays music:
[[MPMusicPlayerController iPodMusicPlayer] playbackState] == MPMusicPlaybackStatePlaying
So, is there any way (may be through calling private methods) to access the song, the car is currently playing?
Source: (StackOverflow)
Is there any way to start playing a song in Google music player app from my app? I am trying following code, but google music player only opens the search results & does not actually play the song.
Intent intent = new Intent();
intent.setAction(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
intent.putExtra(SearchManager.QUERY, "It's my life");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setPackage("com.google.android.music");
activity.startActivity(intent);
The documentation for INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH says following -
An intent to perform a search for music media and automatically play content from the result when possible.
So, according to documentation, it should be able to play the song. But, it only opens the search results and does not play it. Any ideas what I am missing here?
Thanks for any help you can offer.
Source: (StackOverflow)
When you stop your music which is playing in the music player, it doesn't really stop it. It just pauses it, as you are still able to see the music controls after you lock the screen. I want to remove the volume controls (rewind,play,forward) buttons which appear on the locked screen using the code behind. This has already been achieved by an existing app on the marketplace Stop the Music!
. I have gone through this page, but still I am not able to understand how they are able to do so.
Is there anyway to achieve this??
Source: (StackOverflow)
Background: In Android 4.4, Google decided that apps should not have write access to SD cards.
However, apps can write to /SDCard/Android/data/App Package Name.
So this is what I've done. I have written an MP3 file to /Android/data/. I then want this MP3 file to show up in Android music players.
I've tried the following...
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ filePath)));
and....
MediaScannerConnection.scanFile(this,
new String[] { file.toString() }, new String[] {"audio/*"},
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
and...
ContentResolver.requestSync(CreateSyncAccount(context), MediaStore.AUTHORITY, null);
both of these will add the file to the MediaStore as a file with a URI like content://media/external/file/xxxxx
However, the file is not added as audio. I can update the MediaStore to declare the file as audio, but the file metadata isn't imported.
Other than write my own tag reader, how can I get the media scanner to scan the file and insert metadata like it does on the internal memory and pre-KitKat SD cards?
Source: (StackOverflow)
I'm trying to use a SeekBar to display both the length of a track played by a MediaPlayer class and to enable seeking within the track.
Seeking within the track works well. However, updating the progress value using setProgress while the track is playing seems to cause a slight skip.
In the onCreate method I create a Thread with a loop which updates the SeekBar's progress value for the current track. This loop resets when the track is changed.
private void createProgressThread() {
_progressUpdater = new Runnable() {
@Override
public void run() {
//Exitting is set on destroy
while(!_exitting) {
_resetProgress = false;
if(_player.isPlaying()) {
try
{
int current = 0;
int total = _player.getDuration();
progressBar.setMax(total);
progressBar.setIndeterminate(false);
while(_player!=null && current<total && !_resetProgress){
try {
Thread.sleep(1000); //Update once per second
current = _player.getCurrentPosition();
//Removing this line, the track plays normally.
progressBar.setProgress(current);
} catch (InterruptedException e) {
} catch (Exception e){
}
}
}
catch(Exception e)
{
//Don't want this thread to intefere with the rest of the app.
}
}
}
}
};
Thread thread = new Thread(_progressUpdater);
thread.start();
}
Ideally I would rather not use a thread as I understand that this has disadvantages. Also please excuse the exception swallowing - it is difficult to keep checking for all MediaPlayer states in response to UI events. However, my real problem is that the music is skipping.
Could anyone suggest an alternative way to update the progress and explain why the call to setProgress is causing the track to skip even with the use of a seperate thread?
Thanks in advance.
Source: (StackOverflow)
If I play music through iPhone's native music player in iOS 7 and access it on lock screen then I can drag the player's seek bar i.e user can interact with it.
Screenshot :
But if I play music from my app which supports background audio play then the player's seek bar user interaction is disabled on lock screen. I am unable to move it.
Screenshot :
I searched apple's documentation but didn't find anything related to this.
My question is, does iOS allow 3rd party apps to interact with player's seek bar on lock screen like native music app or do I have to add some setting for it in my code ?
Source: (StackOverflow)
I've successfully gotten iOS to play a .mid (midi) file with a soundfont sample using the following code:
-(void) playMusic:(NSString*) name
{
NSString *presetURLPath = [[NSBundle mainBundle] pathForResource:@"GortsMiniPianoJ1" ofType:@"SF2"];
NSURL * presetURL = [NSURL fileURLWithPath:presetURLPath];
[self loadFromDLSOrSoundFont: (NSURL *)presetURL withPatch: (int)3];
NSString *midiFilePath = [[NSBundle mainBundle] pathForResource:name ofType:@"mid"];
NSURL * midiFileURL = [NSURL fileURLWithPath:midiFilePath];
NewMusicPlayer(&musicPlayer);
if (NewMusicSequence(&musicSequence) != noErr)
{
[NSException raise:@"play" format:@"Can't create MusicSequence"];
}
if(MusicSequenceFileLoad(musicSequence, (CFURLRef)midiFileURL, 0, 0 != noErr))
{
[NSException raise:@"play" format:@"Can't load MusicSequence"];
}
MusicPlayerSetSequence(musicPlayer, musicSequence);
MusicSequenceSetAUGraph(musicSequence, _processingGraph);
MusicPlayerPreroll(musicPlayer);
MusicPlayerStart(musicPlayer);
}
However, the problem comes when I then try to play a second file when the first is still playing.
I've tried many variations. Firstly, the above code will play both tracks simultaneously. Or, I've tried:
DisposeMusicPlayer(musicPlayer);
DisposeMusicSequence(musicSequence);
Before the NewMusicPlayer(&musicPlayer)
, but this produces a weird version of the tune with only sporadic notes being played.
I'd love to simply call this method, and the next track to be played.
Source: (StackOverflow)
How to control a music player from buttons in notification, and how to listen button action from the notification
Source: (StackOverflow)
I see that the Song class only contains IsRated
and Rating
property with Set method.
However, I see that the default music player application in WP7 has the ability to rate a song
So, how can I rate a Song ?
Source: (StackOverflow)
Hi im new to swift and i want to know how to play sound in swift 2.0 my code was working in swift 1.0 but now it doesn't work i try this code to play music in MainMenuView :
override func viewDidLoad() {
super.viewDidLoad()
let bgMusicURL:NSURL = NSBundle.mainBundle().URLForResource("Squart-MainMenu", withExtension: "mp3")!
do { bgMusic = try AVAudioPlayer(contentsOfURL: bgMusicURL, fileTypeHint: nil) }
catch _{
return print("no music file")
}
bgMusic.numberOfLoops = 1
bgMusic.prepareToPlay()
if (Data.backgroundMenuPlayed == 0){
bgMusic.play()
Data.backgroundMenuPlayed = 1
}
}
but it throw always the error "NO AUDIO PLAYER" and the music file is in the main folder so i don't think that the music path isn't reachable, any help please ?
Source: (StackOverflow)
I want to make a visualisation for my music player.so that i draw a grid view and i want to change each square colour randomly or continuously.
My Code for draw grid
- (void)drawRect:(CGRect)rect
for (int i = 0; i < 4 ;i = i + 1) {
for (int j = 0; j < 4; j = j + 1) {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 2.0);
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
CGRect rectangle = CGRectMake((j*(100+2))+2,(i*(100+2))+2,100,100);
CGContextAddRect(context, rectangle);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillPath(context);
CGContextStrokePath(context);
}
}
}
it look like
Source: (StackOverflow)