Search code examples
androidaudiomp3oggringtone

Check programmatically if a downloaded MP3/OGG file is valid/complete in android


I am downloading audio files MP3/ OGG programmatically from user provided URLs. I further would proceed to set the downloaded files as ringtone/alarmtone. However, I need to programmatically verify that the file downloaded is a valid MP3/OGG file and is playable. What way can I make sure that the file that has been downloaded is a valid MP3/OGG file and not a junk header from a fake URL.

Code I am using to download :

try {
        URL url = new URL(link);
        httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");
        httpConn.setReadTimeout(20000);
        httpConn.setConnectTimeout(10000);
        httpConn.connect();
        int responseCode = httpConn.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_OK) {
            Log.i(TAG, "http response error code "+responseCode+" for "+name);
            return -1;
        }

        int lenghtOfFile = httpConn.getContentLength();
        Log.d(TAG, "Length of file to download: " + lenghtOfFile + " for " + name + " id_download "+id_download);
        if (lenghtOfFile == -1) {
            return -1; // no length to download
        }
        // input stream to read file - with 8k buffer
        input = new BufferedInputStream(httpConn.getInputStream(),1000000);

        // Delete the outfile first
        File deleteFile = new File(outfile);
        if (deleteFile.exists()) {
            if (deleteFile.delete())
                Log.i(TAG, "File deleted " + outfile);
            else
                Log.i(TAG, "File could'nt be deleted " + outfile);
        }

        output = new FileOutputStream(outfile);
        byte data[] = new byte[1000000];

        long total = 0;
        int progress = 0;
        long mLastUpdate = 0;

        int count = 0;
        while ((count = input.read(data)) != -1) {
            total += count;
            progress = (int) ((total * 100) / lenghtOfFile);
            Log.d(TAG, name + " progress " + progress+"  count "+count+" total "+total);
            output.write(data, 0, count);
            if (System.currentTimeMillis() - mLastUpdate > 1000) {
                mLastUpdate = System.currentTimeMillis();
            }
        }

        output.flush();
    } catch (Exception e) {
        Log.e(TAG, "Exception in downloadUrl() " + e + " for " + name + "  " + id_download + "  "+task_id);
        return -1;
    } finally {
        try {
            if (output != null) {
                output.close();
            }
            if (input != null) {
                input.close();
            }
            if (httpConn != null) {
                httpConn.disconnect();
            }
        } catch (Exception ex) {
            Log.e(TAG,"Exception in close "+ex);
        }
    }

Solution

  • I resolved the issue by using MediaMetadataRetriever classe's API "extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)". This returns a valid duration if its a valid mp3/ ogg file. Else I catch a runtime exception and return from my API.