Search in sources :

Example 6 with CannotWriteException

use of org.jaudiotagger.audio.exceptions.CannotWriteException in project MusicDNA by harjot-oberai.

the class OggVorbisTagWriter method writeRemainingPagesOld.

public void writeRemainingPagesOld(int pageSequence, RandomAccessFile raf, RandomAccessFile rafTemp) throws IOException, CannotReadException, CannotWriteException {
    // Now the Page Sequence Number for all the subsequent pages (containing audio frames) are out because there are
    // less pages before then there used to be, so need to adjust
    long startAudio = raf.getFilePointer();
    long startAudioWritten = rafTemp.getFilePointer();
    logger.fine("Writing audio, audio starts in original file at :" + startAudio + ":Written to:" + startAudioWritten);
    while (raf.getFilePointer() < raf.length()) {
        logger.fine("Reading Ogg Page");
        OggPageHeader nextPage = OggPageHeader.read(raf);
        // Create buffer large enough for next page (header and data) and set byte order to LE so we can use
        // putInt method
        ByteBuffer nextPageHeaderBuffer = ByteBuffer.allocate(nextPage.getRawHeaderData().length + nextPage.getPageLength());
        nextPageHeaderBuffer.order(ByteOrder.LITTLE_ENDIAN);
        nextPageHeaderBuffer.put(nextPage.getRawHeaderData());
        raf.getChannel().read(nextPageHeaderBuffer);
        // Recalculate Page Sequence Number
        nextPageHeaderBuffer.putInt(OggPageHeader.FIELD_PAGE_SEQUENCE_NO_POS, ++pageSequence);
        // Calculate Checksum
        calculateChecksumOverPage(nextPageHeaderBuffer);
        rafTemp.getChannel().write(nextPageHeaderBuffer);
    }
    if ((raf.length() - startAudio) != (rafTemp.length() - startAudioWritten)) {
        throw new CannotWriteException("File written counts don'timer match, file not written");
    }
}
Also used : CannotWriteException(org.jaudiotagger.audio.exceptions.CannotWriteException) OggPageHeader(org.jaudiotagger.audio.ogg.util.OggPageHeader) ByteBuffer(java.nio.ByteBuffer)

Example 7 with CannotWriteException

use of org.jaudiotagger.audio.exceptions.CannotWriteException in project JamsMusicPlayer by psaravan.

the class AsyncAutoGetAlbumArtTask method doInBackground.

@Override
protected Void doInBackground(String... params) {
    //First, we'll go through all the songs in the music library DB and get their attributes.
    dbHelper = new DBAccessHelper(mContext);
    String selection = DBAccessHelper.SONG_SOURCE + "<>" + "'GOOGLE_PLAY_MUSIC'";
    String[] projection = { DBAccessHelper._ID, DBAccessHelper.SONG_FILE_PATH, DBAccessHelper.SONG_ALBUM, DBAccessHelper.SONG_ARTIST, DBAccessHelper.SONG_TITLE };
    Cursor cursor = dbHelper.getWritableDatabase().query(DBAccessHelper.MUSIC_LIBRARY_TABLE, projection, selection, null, null, null, null);
    if (cursor.getCount() != 0) {
        cursor.moveToFirst();
        dataURIsList.add(cursor.getString(1));
        albumsList.add(cursor.getString(2));
        artistsList.add(cursor.getString(3));
        while (cursor.moveToNext()) {
            dataURIsList.add(cursor.getString(1));
            albumsList.add(cursor.getString(2));
            artistsList.add(cursor.getString(3));
        }
    } else {
        //The user doesn't have any music so let's get outta here.
        return null;
    }
    pd.setMax(dataURIsList.size());
    //Now that we have the attributes of the songs, we'll go through them each and check for missing covers.
    for (int i = 0; i < dataURIsList.size(); i++) {
        try {
            file = new File(dataURIsList.get(i));
        } catch (Exception e) {
            continue;
        }
        audioFile = null;
        try {
            audioFile = AudioFileIO.read(file);
        } catch (CannotReadException e2) {
            // TODO Auto-generated catch block
            continue;
        } catch (IOException e2) {
            // TODO Auto-generated catch block
            continue;
        } catch (TagException e2) {
            // TODO Auto-generated catch block
            continue;
        } catch (ReadOnlyFileException e2) {
            // TODO Auto-generated catch block
            continue;
        } catch (InvalidAudioFrameException e2) {
            // TODO Auto-generated catch block
            continue;
        }
        Tag tag = audioFile.getTag();
        //Set the destination directory for the xml file.
        File SDCardRoot = Environment.getExternalStorageDirectory();
        File xmlFile = new File(SDCardRoot, "albumArt.xml");
        if (tag != null) {
            String title = tag.getFirst(FieldKey.TITLE);
            String checkingMessage = mContext.getResources().getString(R.string.checking_if) + " " + title + " " + mContext.getResources().getString(R.string.has_album_art) + ".";
            currentProgress = currentProgress + 1;
            String[] checkingProgressParams = { checkingMessage, "" + currentProgress };
            publishProgress(checkingProgressParams);
            List<Artwork> artworkList = tag.getArtworkList();
            if (artworkList.size() == 0) {
                //Since the file doesn't have any album artwork, we'll have to download it.
                //Get the artist and album name of the file we're working with.
                String artist = tag.getFirst(FieldKey.ARTIST);
                String album = tag.getFirst(FieldKey.ALBUM);
                //Update the progress dialog.
                String message = mContext.getResources().getString(R.string.downloading_artwork_for) + " " + title;
                String[] progressParams = { message, "" + currentProgress };
                publishProgress(progressParams);
                //Remove any unacceptable characters.
                if (artist.contains("#")) {
                    artist = artist.replace("#", "");
                }
                if (artist.contains("$")) {
                    artist = artist.replace("$", "");
                }
                if (artist.contains("@")) {
                    artist = artist.replace("@", "");
                }
                if (album.contains("#")) {
                    album = album.replace("#", "");
                }
                if (album.contains("$")) {
                    album = album.replace("$", "");
                }
                if (album.contains("@")) {
                    album = album.replace("@", "");
                }
                //Replace any spaces in the artist and album fields with "%20".
                if (artist.contains(" ")) {
                    artist = artist.replace(" ", "%20");
                }
                if (album.contains(" ")) {
                    album = album.replace(" ", "%20");
                }
                //Construct the url for the HTTP request.
                URL url = null;
                try {
                    url = new URL("http://itunes.apple.com/search?term=" + artist + "+" + album + "&entity=album");
                } catch (MalformedURLException e1) {
                    // TODO Auto-generated catch block
                    continue;
                }
                String xml = null;
                try {
                    //Create a new HTTP connection.
                    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                    urlConnection.connect();
                    //Check if albumArt.xml already exists and delete it.
                    if (xmlFile.exists()) {
                        xmlFile.delete();
                    }
                    //Create the OuputStream that will be used to store the downloaded data into the file.
                    FileOutputStream fileOutput = new FileOutputStream(xmlFile);
                    //Create the InputStream that will read the data from the HTTP connection.
                    InputStream inputStream = urlConnection.getInputStream();
                    //Total size of target file.
                    int totalSize = urlConnection.getContentLength();
                    //Temp variable that stores the number of downloaded bytes.
                    int downloadedSize = 0;
                    //Create a buffer to store the downloaded bytes.
                    buffer = new byte[1024];
                    int bufferLength = 0;
                    //Now read through the buffer and write the contents to the file.
                    while ((bufferLength = inputStream.read(buffer)) > 0) {
                        fileOutput.write(buffer, 0, bufferLength);
                        downloadedSize += bufferLength;
                    }
                    //Close the File Output Stream.
                    fileOutput.close();
                } catch (MalformedURLException e) {
                    //TODO Auto-generated method stub
                    continue;
                } catch (IOException e) {
                    // TODO Auto-generated method stub
                    continue;
                }
                //Load the XML file into a String variable for local use.
                String xmlAsString = null;
                try {
                    xmlAsString = FileUtils.readFileToString(xmlFile);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                //Extract the albumArt parameter from the XML file.
                artworkURL = StringUtils.substringBetween(xmlAsString, "\"artworkUrl100\":\"", "\",");
                if (artworkURL == null) {
                    //Check and see if a lower resolution image available.
                    artworkURL = StringUtils.substringBetween(xmlAsString, "\"artworkUrl60\":\"", "\",");
                    if (artworkURL == null) {
                    //Can't do anything about that here.
                    } else {
                        //Replace "100x100" with "600x600" to retrieve larger album art images.
                        artworkURL = artworkURL.replace("100x100", "600x600");
                    }
                } else {
                    //Replace "100x100" with "600x600" to retrieve larger album art images.
                    artworkURL = artworkURL.replace("100x100", "600x600");
                }
                //If no URL has been found, there's no point in continuing.
                if (artworkURL != null) {
                    artworkBitmap = null;
                    artworkBitmap = mApp.getImageLoader().loadImageSync(artworkURL);
                    File artworkFile = new File(Environment.getExternalStorageDirectory() + "/artwork.jpg");
                    //Save the artwork.
                    try {
                        FileOutputStream out = new FileOutputStream(artworkFile);
                        artworkBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        Artwork artwork = null;
                        try {
                            artwork = ArtworkFactory.createArtworkFromFile(artworkFile);
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            setArtworkAsFile(artworkFile, dataURIsList.get(i));
                            continue;
                        } catch (ArrayIndexOutOfBoundsException e) {
                            // TODO Auto-generated catch block
                            setArtworkAsFile(artworkFile, dataURIsList.get(i));
                            continue;
                        } catch (Exception e) {
                            e.printStackTrace();
                            setArtworkAsFile(artworkFile, dataURIsList.get(i));
                            continue;
                        } catch (Error e) {
                            e.printStackTrace();
                            setArtworkAsFile(artworkFile, dataURIsList.get(i));
                            continue;
                        }
                        if (artwork != null) {
                            try {
                                //Remove the current artwork field and recreate it.
                                tag.deleteArtworkField();
                                tag.addField(artwork);
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                setArtworkAsFile(artworkFile, dataURIsList.get(i));
                                continue;
                            } catch (Error e) {
                                e.printStackTrace();
                                setArtworkAsFile(artworkFile, dataURIsList.get(i));
                                continue;
                            }
                            try {
                                audioFile.commit();
                            } catch (CannotWriteException e) {
                                // TODO Auto-generated catch block
                                setArtworkAsFile(artworkFile, dataURIsList.get(i));
                                continue;
                            } catch (Error e) {
                                e.printStackTrace();
                                setArtworkAsFile(artworkFile, dataURIsList.get(i));
                                continue;
                            }
                        }
                        //Delete the temporary files that we stored during the fetching process.
                        if (artworkFile.exists()) {
                            artworkFile.delete();
                        }
                        if (xmlFile.exists()) {
                            xmlFile.delete();
                        }
                        //Set the files to null to help clean up memory.
                        artworkBitmap = null;
                        audioFile = null;
                        tag = null;
                        xmlFile = null;
                        artworkFile = null;
                    }
                }
            }
        }
    }
    audioFile = null;
    file = null;
    return null;
}
Also used : CannotWriteException(org.jaudiotagger.audio.exceptions.CannotWriteException) MalformedURLException(java.net.MalformedURLException) Artwork(org.jaudiotagger.tag.images.Artwork) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException) DBAccessHelper(com.jams.music.player.DBHelpers.DBAccessHelper) InputStream(java.io.InputStream) InvalidAudioFrameException(org.jaudiotagger.audio.exceptions.InvalidAudioFrameException) IOException(java.io.IOException) Cursor(android.database.Cursor) ReadOnlyFileException(org.jaudiotagger.audio.exceptions.ReadOnlyFileException) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException) CannotWriteException(org.jaudiotagger.audio.exceptions.CannotWriteException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) TagException(org.jaudiotagger.tag.TagException) InvalidAudioFrameException(org.jaudiotagger.audio.exceptions.InvalidAudioFrameException) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) TagException(org.jaudiotagger.tag.TagException) FileOutputStream(java.io.FileOutputStream) ReadOnlyFileException(org.jaudiotagger.audio.exceptions.ReadOnlyFileException) Tag(org.jaudiotagger.tag.Tag) AudioFile(org.jaudiotagger.audio.AudioFile) File(java.io.File)

Example 8 with CannotWriteException

use of org.jaudiotagger.audio.exceptions.CannotWriteException in project JamsMusicPlayer by psaravan.

the class AsyncDeleteAlbumArtTask method doInBackground.

@Override
protected Void doInBackground(String... params) {
    if (params.length == 2) {
        artist = params[0];
        album = params[1];
    }
    //Remove the + and replace them back with spaces. Also replace any rogue apostrophes.
    try {
        if (album.contains("+")) {
            album = album.replace("+", " ");
        }
        if (album.contains("'")) {
            album = album.replace("'", "''");
        }
        if (artist.contains("+")) {
            artist = artist.replace("+", " ");
        }
        if (artist.contains("'")) {
            artist = artist.replace("'", "''");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    String selection = DBAccessHelper.SONG_ALBUM + "=" + "'" + album + "'" + " AND " + DBAccessHelper.SONG_ARTIST + "=" + "'" + artist + "'";
    String[] projection = { DBAccessHelper._ID, DBAccessHelper.SONG_FILE_PATH, DBAccessHelper.SONG_ALBUM_ART_PATH };
    Cursor cursor = mApp.getDBAccessHelper().getWritableDatabase().query(DBAccessHelper.MUSIC_LIBRARY_TABLE, projection, selection, null, null, null, null);
    cursor.moveToFirst();
    if (cursor.getCount() != 0) {
        dataURIsList.add(cursor.getString(1));
        albumArtPathsList.add(cursor.getString(2));
    }
    while (cursor.moveToNext()) {
        dataURIsList.add(cursor.getString(1));
        albumArtPathsList.add(cursor.getString(2));
    }
    for (int i = 0; i < dataURIsList.size(); i++) {
        File audioFile = new File(dataURIsList.get(i));
        AudioFile f = null;
        try {
            f = AudioFileIO.read(audioFile);
        } catch (CannotReadException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TagException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ReadOnlyFileException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidAudioFrameException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Tag tag = null;
        if (f != null) {
            tag = f.getTag();
        } else {
            continue;
        }
        try {
            tag.deleteArtworkField();
        } catch (KeyNotFoundException e) {
            Toast.makeText(mContext, R.string.album_doesnt_have_artwork, Toast.LENGTH_LONG).show();
        }
        try {
            f.commit();
        } catch (CannotWriteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //Check if the current song's album art is a JPEG file.
        if (albumArtPathsList.get(i).startsWith("/")) {
            File file = new File(albumArtPathsList.get(i));
            if (file != null) {
                if (file.exists()) {
                    file.delete();
                }
            }
        }
        //Remove the album art from the album art database.
        String filePath = dataURIsList.get(i);
        filePath = filePath.replace("'", "''");
        String where = DBAccessHelper.SONG_FILE_PATH + "=" + "'" + filePath + "'";
        ContentValues values = new ContentValues();
        values.put(DBAccessHelper.SONG_ALBUM_ART_PATH, "");
        mApp.getDBAccessHelper().getWritableDatabase().update(DBAccessHelper.MUSIC_LIBRARY_TABLE, values, where, null);
    }
    //Refresh the memory/disk cache.
    mApp.getImageLoader().clearDiscCache();
    mApp.getImageLoader().clearMemoryCache();
    cursor.close();
    cursor = null;
    return null;
}
Also used : CannotWriteException(org.jaudiotagger.audio.exceptions.CannotWriteException) ContentValues(android.content.ContentValues) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException) InvalidAudioFrameException(org.jaudiotagger.audio.exceptions.InvalidAudioFrameException) IOException(java.io.IOException) Cursor(android.database.Cursor) ReadOnlyFileException(org.jaudiotagger.audio.exceptions.ReadOnlyFileException) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException) KeyNotFoundException(org.jaudiotagger.tag.KeyNotFoundException) IOException(java.io.IOException) TagException(org.jaudiotagger.tag.TagException) InvalidAudioFrameException(org.jaudiotagger.audio.exceptions.InvalidAudioFrameException) CannotWriteException(org.jaudiotagger.audio.exceptions.CannotWriteException) AudioFile(org.jaudiotagger.audio.AudioFile) TagException(org.jaudiotagger.tag.TagException) ReadOnlyFileException(org.jaudiotagger.audio.exceptions.ReadOnlyFileException) Tag(org.jaudiotagger.tag.Tag) File(java.io.File) AudioFile(org.jaudiotagger.audio.AudioFile) KeyNotFoundException(org.jaudiotagger.tag.KeyNotFoundException)

Example 9 with CannotWriteException

use of org.jaudiotagger.audio.exceptions.CannotWriteException in project Shuttle by timusus.

the class TaggerTask method doInBackground.

@Override
protected Boolean doInBackground(Object... params) {
    boolean success = false;
    boolean requiresPermission = TaggerUtils.requiresPermission(paths);
    for (int i = 0; i < paths.size(); i++) {
        final String path = paths.get(i);
        try {
            File orig = new File(path);
            AudioFile audioFile = AudioFileIO.read(orig);
            Tag tag = audioFile.getTag();
            if (tag == null) {
                break;
            }
            TagUpdate tagUpdate = new TagUpdate(tag);
            tagUpdate.softSetArtist(artistText);
            tagUpdate.softSetAlbumArtist(albumArtistText);
            tagUpdate.softSetGenre(genreText);
            tagUpdate.softSetYear(yearText);
            if (showAlbum) {
                tagUpdate.softSetAlbum(albumText);
                tagUpdate.softSetDiscTotal(discTotalText);
            }
            if (showTrack) {
                tagUpdate.softSetTitle(titleText);
                tagUpdate.softSetTrack(trackText);
                tagUpdate.softSetTrackTotal(trackTotalText);
                tagUpdate.softSetDisc(discText);
                tagUpdate.softSetLyrics(lyricsText);
                tagUpdate.softSetComment(commentText);
            }
            File temp = null;
            if (tagUpdate.hasChanged()) {
                if (TaggerUtils.requiresPermission(paths)) {
                    temp = new File(ShuttleApplication.getInstance().getFilesDir(), orig.getName());
                    tempFiles.add(temp);
                    TaggerUtils.copyFile(orig, temp);
                    audioFile = AudioFileIO.read(temp);
                    tag = audioFile.getTag();
                    if (tag == null) {
                        break;
                    }
                }
                tagUpdate.updateTag(tag);
                AudioFileIO.write(audioFile);
                if (requiresPermission && temp != null) {
                    DocumentFile documentFile = documentFiles.get(i);
                    if (documentFile != null) {
                        ParcelFileDescriptor pfd = ShuttleApplication.getInstance().getContentResolver().openFileDescriptor(documentFile.getUri(), "w");
                        if (pfd != null) {
                            FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor());
                            TaggerUtils.copyFile(temp, fileOutputStream);
                            pfd.close();
                        }
                        if (temp.delete()) {
                            if (tempFiles.contains(temp)) {
                                tempFiles.remove(temp);
                            }
                        }
                    }
                }
            }
            publishProgress(i);
            success = true;
        } catch (CannotWriteException | IOException | CannotReadException | InvalidAudioFrameException | TagException | ReadOnlyFileException e) {
            e.printStackTrace();
        } finally {
            // Try to clean up our temp files
            if (tempFiles != null && tempFiles.size() != 0) {
                for (int j = tempFiles.size() - 1; j >= 0; j--) {
                    File file = tempFiles.get(j);
                    file.delete();
                    tempFiles.remove(j);
                }
            }
        }
    }
    return success;
}
Also used : CannotWriteException(org.jaudiotagger.audio.exceptions.CannotWriteException) DocumentFile(android.support.v4.provider.DocumentFile) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException) InvalidAudioFrameException(org.jaudiotagger.audio.exceptions.InvalidAudioFrameException) IOException(java.io.IOException) TagUpdate(com.simplecity.amp_library.model.TagUpdate) AudioFile(org.jaudiotagger.audio.AudioFile) TagException(org.jaudiotagger.tag.TagException) FileOutputStream(java.io.FileOutputStream) ParcelFileDescriptor(android.os.ParcelFileDescriptor) ReadOnlyFileException(org.jaudiotagger.audio.exceptions.ReadOnlyFileException) Tag(org.jaudiotagger.tag.Tag) File(java.io.File) AudioFile(org.jaudiotagger.audio.AudioFile) DocumentFile(android.support.v4.provider.DocumentFile)

Example 10 with CannotWriteException

use of org.jaudiotagger.audio.exceptions.CannotWriteException in project MusicDNA by harjot-oberai.

the class FlacTagWriter method write.

/**
 * Write tag to file
 *
 * @param tag
 * @param raf
 * @param rafTemp
 * @throws CannotWriteException
 * @throws IOException
 */
public void write(Tag tag, RandomAccessFile raf, RandomAccessFile rafTemp) throws CannotWriteException, IOException {
    logger.config("Writing tag");
    MetadataBlockInfo blockInfo = new MetadataBlockInfo();
    // Read existing data
    FlacStreamReader flacStream = new FlacStreamReader(raf);
    try {
        flacStream.findStream();
    } catch (CannotReadException cre) {
        throw new CannotWriteException(cre.getMessage());
    }
    boolean isLastBlock = false;
    while (!isLastBlock) {
        try {
            MetadataBlockHeader mbh = MetadataBlockHeader.readHeader(raf);
            if (mbh.getBlockType() != null) {
                switch(mbh.getBlockType()) {
                    case STREAMINFO:
                        {
                            blockInfo.streamInfoBlock = new MetadataBlock(mbh, new MetadataBlockDataStreamInfo(mbh, raf));
                            break;
                        }
                    case VORBIS_COMMENT:
                    case PADDING:
                    case PICTURE:
                        {
                            // All these will be replaced by the new metadata so we just treat as padding in order
                            // to determine how much space is already allocated in the file
                            raf.seek(raf.getFilePointer() + mbh.getDataLength());
                            MetadataBlockData mbd = new MetadataBlockDataPadding(mbh.getDataLength());
                            blockInfo.metadataBlockPadding.add(new MetadataBlock(mbh, mbd));
                            break;
                        }
                    case APPLICATION:
                        {
                            MetadataBlockData mbd = new MetadataBlockDataApplication(mbh, raf);
                            blockInfo.metadataBlockApplication.add(new MetadataBlock(mbh, mbd));
                            break;
                        }
                    case SEEKTABLE:
                        {
                            MetadataBlockData mbd = new MetadataBlockDataSeekTable(mbh, raf);
                            blockInfo.metadataBlockSeekTable.add(new MetadataBlock(mbh, mbd));
                            break;
                        }
                    case CUESHEET:
                        {
                            MetadataBlockData mbd = new MetadataBlockDataCueSheet(mbh, raf);
                            blockInfo.metadataBlockCueSheet.add(new MetadataBlock(mbh, mbd));
                            break;
                        }
                    default:
                        {
                            // What are the consequences of doing this
                            raf.seek(raf.getFilePointer() + mbh.getDataLength());
                            break;
                        }
                }
            }
            isLastBlock = mbh.isLastBlock();
        } catch (CannotReadException cre) {
            throw new CannotWriteException(cre.getMessage());
        }
    }
    // Number of bytes in the existing file available before audio data
    int availableRoom = computeAvailableRoom(blockInfo);
    // Minimum Size of the New tag data without padding
    int newTagSize = tc.convert(tag).limit();
    // Number of bytes required for new tagdata and other metadata blocks
    int neededRoom = newTagSize + computeNeededRoom(blockInfo);
    // Go to start of Flac within file
    raf.seek(flacStream.getStartOfFlacInFile());
    logger.config("Writing tag available bytes:" + availableRoom + ":needed bytes:" + neededRoom);
    // adjust padding accordingly need to allow space for padding header if padding required
    if ((availableRoom == neededRoom) || (availableRoom > neededRoom + MetadataBlockHeader.HEADER_LENGTH)) {
        // Jump over Id3 (if exists) Flac and StreamInfoBlock
        raf.seek(flacStream.getStartOfFlacInFile() + FlacStreamReader.FLAC_STREAM_IDENTIFIER_LENGTH);
        // Write StreamInfo, we always write this first even if wasn'timer first in original spec
        raf.write(blockInfo.streamInfoBlock.getHeader().getBytesWithoutIsLastBlockFlag());
        raf.write(blockInfo.streamInfoBlock.getData().getBytes());
        // Write Application Blocks
        for (MetadataBlock aMetadataBlockApplication : blockInfo.metadataBlockApplication) {
            raf.write(aMetadataBlockApplication.getHeader().getBytesWithoutIsLastBlockFlag());
            raf.write(aMetadataBlockApplication.getData().getBytes());
        }
        // Write Seek Table Blocks
        for (MetadataBlock aMetadataBlockSeekTable : blockInfo.metadataBlockSeekTable) {
            raf.write(aMetadataBlockSeekTable.getHeader().getBytesWithoutIsLastBlockFlag());
            raf.write(aMetadataBlockSeekTable.getData().getBytes());
        }
        // Write Cue sheet Blocks
        for (MetadataBlock aMetadataBlockCueSheet : blockInfo.metadataBlockCueSheet) {
            raf.write(aMetadataBlockCueSheet.getHeader().getBytesWithoutIsLastBlockFlag());
            raf.write(aMetadataBlockCueSheet.getData().getBytes());
        }
        // Write tag (and padding)
        raf.getChannel().write(tc.convert(tag, availableRoom - neededRoom));
    } else // Need to move audio
    {
        // If Flac tag contains ID3header or something before start of official Flac header copy it over
        if (flacStream.getStartOfFlacInFile() > 0) {
            raf.seek(0);
            rafTemp.getChannel().transferFrom(raf.getChannel(), 0, flacStream.getStartOfFlacInFile());
            rafTemp.seek(flacStream.getStartOfFlacInFile());
        }
        rafTemp.writeBytes(FlacStreamReader.FLAC_STREAM_IDENTIFIER);
        // To ensure never set Last-metadata-block flag even if was before
        rafTemp.writeByte(0);
        int uptoStreamHeaderSize = flacStream.getStartOfFlacInFile() + FlacStreamReader.FLAC_STREAM_IDENTIFIER_LENGTH + MetadataBlockHeader.BLOCK_TYPE_LENGTH;
        rafTemp.seek(uptoStreamHeaderSize);
        raf.seek(uptoStreamHeaderSize);
        rafTemp.getChannel().transferFrom(raf.getChannel(), uptoStreamHeaderSize, MetadataBlockHeader.BLOCK_LENGTH + MetadataBlockDataStreamInfo.STREAM_INFO_DATA_LENGTH);
        int dataStartSize = flacStream.getStartOfFlacInFile() + FlacStreamReader.FLAC_STREAM_IDENTIFIER_LENGTH + MetadataBlockHeader.HEADER_LENGTH + MetadataBlockDataStreamInfo.STREAM_INFO_DATA_LENGTH;
        rafTemp.seek(dataStartSize);
        // Write all the metadatablocks
        for (MetadataBlock aMetadataBlockApplication : blockInfo.metadataBlockApplication) {
            rafTemp.write(aMetadataBlockApplication.getHeader().getBytesWithoutIsLastBlockFlag());
            rafTemp.write(aMetadataBlockApplication.getData().getBytes());
        }
        for (MetadataBlock aMetadataBlockSeekTable : blockInfo.metadataBlockSeekTable) {
            rafTemp.write(aMetadataBlockSeekTable.getHeader().getBytesWithoutIsLastBlockFlag());
            rafTemp.write(aMetadataBlockSeekTable.getData().getBytes());
        }
        for (MetadataBlock aMetadataBlockCueSheet : blockInfo.metadataBlockCueSheet) {
            rafTemp.write(aMetadataBlockCueSheet.getHeader().getBytesWithoutIsLastBlockFlag());
            rafTemp.write(aMetadataBlockCueSheet.getData().getBytes());
        }
        // Write tag data use default padding
        rafTemp.write(tc.convert(tag, FlacTagCreator.DEFAULT_PADDING).array());
        // Write audio to new file
        raf.seek(dataStartSize + availableRoom);
        // Issue #385
        // Transfer 'size' bytes from raf at its current position to rafTemp at position but do it in batches
        // to prevent OutOfMemory exceptions
        long amountToBeWritten = raf.getChannel().size() - raf.getChannel().position();
        long written = 0;
        long chunksize = TagOptionSingleton.getInstance().getWriteChunkSize();
        long count = amountToBeWritten / chunksize;
        long mod = amountToBeWritten % chunksize;
        for (int i = 0; i < count; i++) {
            written += rafTemp.getChannel().transferFrom(raf.getChannel(), rafTemp.getChannel().position(), chunksize);
            rafTemp.getChannel().position(rafTemp.getChannel().position() + chunksize);
        }
        written += rafTemp.getChannel().transferFrom(raf.getChannel(), rafTemp.getChannel().position(), mod);
        if (written != amountToBeWritten) {
            throw new CannotWriteException("Was meant to write " + amountToBeWritten + " bytes but only written " + written + " bytes");
        }
    }
}
Also used : CannotWriteException(org.jaudiotagger.audio.exceptions.CannotWriteException) CannotReadException(org.jaudiotagger.audio.exceptions.CannotReadException)

Aggregations

CannotWriteException (org.jaudiotagger.audio.exceptions.CannotWriteException)15 CannotReadException (org.jaudiotagger.audio.exceptions.CannotReadException)12 IOException (java.io.IOException)10 File (java.io.File)9 AudioFile (org.jaudiotagger.audio.AudioFile)9 InvalidAudioFrameException (org.jaudiotagger.audio.exceptions.InvalidAudioFrameException)7 ReadOnlyFileException (org.jaudiotagger.audio.exceptions.ReadOnlyFileException)7 Tag (org.jaudiotagger.tag.Tag)7 TagException (org.jaudiotagger.tag.TagException)6 FileOutputStream (java.io.FileOutputStream)4 ContentValues (android.content.ContentValues)3 Cursor (android.database.Cursor)3 ByteBuffer (java.nio.ByteBuffer)3 FieldDataInvalidException (org.jaudiotagger.tag.FieldDataInvalidException)3 KeyNotFoundException (org.jaudiotagger.tag.KeyNotFoundException)3 Intent (android.content.Intent)2 ParcelFileDescriptor (android.os.ParcelFileDescriptor)2 DocumentFile (android.support.v4.provider.DocumentFile)2 DBAccessHelper (com.jams.music.player.DBHelpers.DBAccessHelper)2 TagUpdate (com.simplecity.amp_library.model.TagUpdate)2