• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

MediaPlayer cannot play downloaded mp3 file

duykienvp

Lurker
My application gets playlist from a XML file, requests URL of mp3 file from server, downloads and plays it.
It was able to download mp3 file but unable to play it.
When I used emulator with Android 2.1, it was displayed in LogCat:
10-23 11:23:09.058: INFO/---AndroidMediaPlayer(227): downloaded : /sdcard/track042298.mp3

10-23 11:23:09.058: INFO/---AndroidMediaPlayer(227): musicFile = /sdcard/track042298.mp3

10-23 11:23:09.068: INFO/---AndroidMediaPlayer(227): musicFile exist = true

10-23 11:23:09.078: INFO/---AndroidMediaPlayer(227): music file length = 4033308

10-23 11:23:10.397: WARN/MediaPlayer(227): info/warning (1, 26)

10-23 11:23:10.417: ERROR/PlayerDriver(31): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported

10-23 11:23:10.427: ERROR/MediaPlayer(227): error (1, -4)

10-23 11:23:10.427: WARN/System.err(227): java.io.IOException: Prepare failed.: status=0x1

10-23 11:23:10.450: WARN/PlayerDriver(31): PVMFInfoErrorHandlingComplete

10-23 11:23:10.497: WARN/System.err(227): at android.media.MediaPlayer.prepare(Native Method)

10-23 11:23:10.497: WARN/System.err(227): at org.me.androidmediaplayer.AndroidMediaPlayer$PlaylistClick.onItemClick(AndroidMediaPlayer.java:303)

10-23 11:23:10.497: WARN/System.err(227): at android.widget.AdapterView.performItemClick(AdapterView.java:284)

10-23 11:23:10.507: WARN/System.err(227): at android.widget.ListView.performItemClick(ListView.java:3285)

10-23 11:23:10.518: WARN/System.err(227): at android.widget.AbsListView$PerformClick.run(AbsListView.java:1640)

10-23 11:23:10.518: WARN/System.err(227): at android.os.Handler.handleCallback(Handler.java:587)

10-23 11:23:10.518: WARN/System.err(227): at android.os.Handler.dispatchMessage(Handler.java:92)

10-23 11:23:10.518: WARN/System.err(227): at android.os.Looper.loop(Looper.java:123)

10-23 11:23:10.527: WARN/System.err(227): at android.app.ActivityThread.main(ActivityThread.java:4363)

10-23 11:23:10.527: WARN/System.err(227): at java.lang.reflect.Method.invokeNative(Native Method)

10-23 11:23:10.527: WARN/System.err(227): at java.lang.reflect.Method.invoke(Method.java:521)

10-23 11:23:10.537: WARN/System.err(227): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)

10-23 11:23:10.537: WARN/System.err(227): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

10-23 11:23:10.537: WARN/System.err(227): at dalvik.system.NativeStart.main(Native Method)

10-23 11:23:10.647: INFO/MediaPlayer(227): Info (1,26)

10-23 11:24:27.658: INFO/---AndroidMediaPlayer(227): tvPlayPause text = Play

10-23 11:24:27.658: INFO/---AndroidMediaPlayer(227): tvPlayPause text changed to: Pause

10-23 11:24:27.698: ERROR/MediaPlayer(227): start called in state 0

10-23 11:24:27.698: ERROR/MediaPlayer(227): error (-38, 0)

10-23 11:24:27.784: ERROR/MediaPlayer(227): Error (-38,0)
Mp3 file downloaded, exists and has length but MediaPlayer couldn't play it.
This happened at setDataSource() method.

When I used emulator with Android 2.2, it could be prepared but MediaPlayer still couldn't play it with error (1, -2147483648).

When I used my download method to download that file and saved to my hard disk, Window Media Player could play normally.

I have googled for many days but nothing works.

Please help.

Code:
package org.me.androidmediaplayer;

import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.*;
import android.widget.AdapterView.OnItemClickListener;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Music Player
 * @author Duy Kien
 */
public class AndroidMediaPlayer extends Activity {
    //song list Url
    private final String songListUrl =
                            "http://aladdins.vn/nghenhac/playlist.xml";
    //server Url
    private final String serverUrl =
                            "http://aladdins.vn/nghenhac/getMusic.do";

    //views of layout
    private ImageButton ibtnStop, ibtnPlayPause, ibtnReset;
    private TextView tvPlayPause, tvStatus;
    private ListView lvPlaylist;

    //media player to play mp3 files
    private MediaPlayer mp;

    //songs list
    private int nSongs = 0;
    private int[] iSongID;
    private String[] sSongID;
    private String[] songs;
    private ArrayAdapter<String> songList;
    
    //list of temp file path
    private String[] filePaths;

    //boolean array to check if a song downloaded before
    boolean[] downloaded;

    //file to store mp3 file received from server
    private String musicFile;

    //log string
    private static final String TAG = "---AndroidMediaPlayer";

    /** Called when the activity is first created. */
    @Override
    public void onCreate( Bundle icicle ) {
        super.onCreate( icicle );
        setContentView( R.layout.main );

        mp = new MediaPlayer();

        //take views of layout
        getViews();

        //get playlist from server
        getPlaylist( songListUrl );

        //create array adapter for ListView
        songList = new ArrayAdapter<String>( this.getApplicationContext(),
                                             R.layout.list_item,
                                             songs );
        lvPlaylist.setAdapter( songList );
        lvPlaylist.setVisibility(ListView.VISIBLE);

        //initialize
        downloaded = new boolean[ nSongs ];
        for (int i = 0; i < downloaded.length; i++)
            downloaded[i] = false;

        filePaths = new String[ nSongs ];
    } //end onCreate

    /**
     * Take views of layout
     */
    private void getViews() {
        //find views from layout
        tvPlayPause   = (TextView)    findViewById ( R.id.tvPlayPause );
        tvStatus      = (TextView)    findViewById ( R.id.tvStatus );
        ibtnStop      = (ImageButton) findViewById ( R.id.ibtnStop );
        ibtnPlayPause = (ImageButton) findViewById ( R.id.ibtnPlayPause );
        ibtnReset       = (ImageButton) findViewById ( R.id.ibtnReset );
        lvPlaylist    = (ListView)    findViewById ( R.id.lvSongs );

        //Stop button
        ibtnStop.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                mp.stop();
                tvStatus.setText("Stopped");
                tvPlayPause.setText(R.string.play);
                ibtnPlayPause.setImageResource(R.drawable.play);
            } //end onClick
        }); //end setOnClickListener

        //Play or Pause button        
        ibtnPlayPause.setOnClickListener(new OnClickListener(){
            public void onClick(View view) {
                //if current text is "Play"
                //then play music and change textview and image
                //else
                //then stop music and change textview and image                   
                if ( tvPlayPause.getText().equals("Pause")) {
                    tvStatus.setText( "Paused" );
                    tvPlayPause.setText( R.string.play );
                    ibtnPlayPause.setImageResource( R.drawable.play );
                    mp.pause();                  
                } //end if
                
                else {
                        Log.i(TAG, "tvPlayPause text = " + tvPlayPause.getText());
                    tvStatus.setText( "Playing..." );
                    tvPlayPause.setText( R.string.pause );
                        Log.i(TAG, "tvPlayPause text changed to: " + tvPlayPause.getText());
                    ibtnPlayPause.setImageResource( R.drawable.pause );
                    mp.start();
                } //end else
            } // end onClick
        });//end setOnClickListener

        //Reset button
        ibtnReset.setOnClickListener( new OnClickListener () {
            public void onClick ( View view )
            {
                mp.seekTo(0);
            } //end onClick
        }); //end setOnClickListener

        //List view Playlist
        lvPlaylist.setOnItemClickListener(new PlaylistClick());
    } //end getViews

    /**
     * Get songs list from given Url
     * @param Url
     */
    private void getPlaylist( String url ) {
        //input stream for reading content of Url
        HttpURLConnection httpConnection;
        InputStream inStream    = null;
        
        try {
            //create a connection from given Url
            httpConnection = createHttpConnection( url );
            if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK)
                inStream = httpConnection.getInputStream();

            //xml file contains song List
            Document xmlSongList = null;

            //builder to build xml file
            DocumentBuilder db;
            DocumentBuilderFactory dbf =
                    DocumentBuilderFactory.newInstance();

            db          = dbf.newDocumentBuilder();
            xmlSongList = db.parse( inStream );

            xmlSongList.getDocumentElement().normalize();

            //retrieve all <song> node
            NodeList playlistNode  = xmlSongList.getElementsByTagName( "playList" );
            Element root            = (Element) playlistNode.item(0);
            NodeList songNodes     = root.getElementsByTagName("song");
            nSongs = songNodes.getLength();
            iSongID = new int[ nSongs ];
            sSongID = new String[ nSongs ];
            songs = new String[ nSongs ];
            
            //retrive song information
            for (int i = 0; i < nSongs; i++) {
                Element songNode = (Element) songNodes.item( i );
                
                //get song title
                Node titleNode = (Node) songNode.getElementsByTagName("title").item(0);
                Node titleNodeValue = titleNode.getFirstChild();
                songs[ i ]       = titleNodeValue.getNodeValue();

                //get song ID
                Node idNode      = (Node) songNode.getElementsByTagName("id").item(0);
                Node idNodeValue = idNode.getFirstChild();
                sSongID[ i ]     = idNodeValue.getNodeValue();
                iSongID[ i ]     = Integer.parseInt( sSongID[ i ] );
            } //end for
            httpConnection.disconnect();
            inStream.close();
        } // end try
        catch (Exception ex) {
            ex.printStackTrace();
        } //end catch       
    }//end getPlaylist

    /**
     * Create an HttpConnection from given Url
     * @param Url URL to make connection
     * @return HttpURLConnection from Url in HTTP form
     */
    private HttpURLConnection createHttpConnection(String urlString)
            throws IOException {
        
        HttpURLConnection httpConnection;

        try {       
            //open connection from given URL
            URL url = new URL(urlString);
            URLConnection connection = url.openConnection();
        
            if (!(connection instanceof HttpURLConnection ))
                throw new IOException("Not a HTTP connection");
            
            //connect to url in HTTP form
            httpConnection = (HttpURLConnection) connection;
            httpConnection.setAllowUserInteraction(false);
            httpConnection.setInstanceFollowRedirects(true);
            httpConnection.setRequestMethod("GET");
            httpConnection.connect();
            
        } //end try  
        catch (IOException ex) {
            throw ex;
        } // end catch        
        
        return httpConnection;
    } //end createHttpConnection

    /**
     * Perform action when a track is clicked
     * @author Duy Kien
     *
     */
    class PlaylistClick implements OnItemClickListener {

        public void onItemClick(AdapterView<?> list, View view,
                              int position, long id) {
            
            Log.i(TAG, "play track at " + (position + 1));
            
            /*
            try {
                mp = new MediaPlayer();
                mp.setDataSource(getFileUrl(position));
                mp.prepare();
            } //end try
            catch (Exception ex) {
                ex.printStackTrace();
            } //end catch
            */
            
            //if this song was downloaded before
            if ( downloaded[ position ] ) {
                musicFile = filePaths[ position ];
            } //end if
            ////if this song was NOT downloaded before
            else {
                tvStatus.setText( "Downloading..." );
                
                    Log.i(TAG, "Downloading...");
                
                tvStatus.postInvalidate();
                
                musicFile = downloadFile( position );
                
                    Log.i(TAG, "musicFile = " + musicFile);
                    
                tvStatus.setText( "Download completed" );
                tvStatus.postInvalidate();
                
                //remember that this track is downloaded 
                downloaded[ position ] = true;
                filePaths[ position ]  = musicFile;
            } //end else
            
            //prepare to play
            try {
                FileInputStream fis = new FileInputStream( musicFile );
                File newFile         = new File( musicFile );
                    Log.i(TAG, "musicFile exist = " + newFile.exists());
                    Log.i(TAG, "music file length = " + newFile.length());
                mp.setDataSource( fis.getFD(), 0, newFile.length() );
                mp.prepare();
                    
                    Log.i(TAG, "prepared music file");      
            } // end try
            catch (Exception ex){
                ex.printStackTrace();
            } //end catch
        }      //end onItenClick
    }           //end PlaylistClick

    /**
     * Download mp3 file with given ID from server
     * @param id id of mp3 file to download
     * @return path to temporary file
     */
    private String downloadFile(int id) {
        String fileUrl  = "";
        String filePath = null;
        
        try {
            //get URL of mp3 file
            fileUrl = getFileUrl(id);
                Log.i(TAG, "fileUrl = " + fileUrl);

            //create input stream for downloading file
            HttpURLConnection connection = createHttpConnection(fileUrl);
            
            InputStream inStream = null;
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK)
                inStream = connection.getInputStream();
            DataInputStream dataInputStream = new DataInputStream(inStream);
            
            //create temp file
            File temp = File.createTempFile("track" + String.valueOf(id),
                                                ".mp3");
            temp.deleteOnExit();
            filePath = temp.getAbsolutePath();
                Log.i(TAG, "begin download file: " + filePath);

            FileOutputStream outFile = new FileOutputStream(temp);

            int bufferSize = 1024;
            byte buffer[]  = new byte[ bufferSize ];

            do {
                int numberRead = dataInputStream.read(buffer);
                if (numberRead <= 0)
                    break;
                outFile.write(buffer, 0, numberRead);
                
                buffer = new byte[ bufferSize ];
            } while (true);

            //close connection
            dataInputStream.close();
            inStream.close();
            connection.disconnect();
            
            outFile.flush();
            outFile.close();
                Log.i(TAG, "downloaded : " + filePath);
        } //end try
        catch (Exception ex){
            ex.printStackTrace();
        } // end catch

        return filePath;
    } //end downloadFile
    
    /**
     * Get URL of clicked track from server
     * @param id id of clicked track
     * @return URL of clicked track
     */
    private String getFileUrl(int id) {
        String fileUrl = "";
        String request = serverUrl;
        
        try {
            //instantiate a HTTP Client
            DefaultHttpClient client = new DefaultHttpClient();

            //add request parameter
            request += ( "?id=0" + (id + 1)); 
            
            //instantiate a HTTP method
            HttpGet method = new HttpGet(request);
        
            //execute GET method
            HttpResponse response =  client.execute(method);
         
            //get response and retrieve file URL
            InputStream dataResponse = response.getEntity().getContent();
         
            DataInputStream inStream = new DataInputStream( dataResponse );
            
            inStream.readShort();
            inStream.read();
            fileUrl = inStream.readUTF();
            
            //close connection
            inStream.close();
        } //end try
        catch (Exception ex) {
            ex.printStackTrace();
            
        } //end catch
        return fileUrl;
    }//end getFileUrl
} //end AndroidMediaPlayer
 
Digital Rights management. Basically all mp3s bought from itunes store have drm, which only allows them to be played in itunes or an ipod.
 
I just downloaded that mp3 file from a web server and i couldn't find drm inside it.

I've googled for many days and really exhausted :(.

I dont know how to solve this........
 
the only thing that you are doing differently than anyone else, is the way you are fetching them from a server. Since nothing else seems to be wrong, I would have to say thats your problem. Have you tried putting the files on the phone manually just to see if they play?
 
Back
Top Bottom