Exemplo n.º 1
0
int
main(int argc, char** argv)
{
    static struct option long_options[] = {
        { "help",    0, 0, OPT_HELP    },
        { "version", 0, 0, OPT_VERSION },
        { "album",   1, 0, OPT_ALBUM   },
        { "artist",  1, 0, OPT_ARTIST  },
        { "comment", 1, 0, OPT_COMMENT },
        { "disk",    1, 0, OPT_DISK    },
        { "disks",   1, 0, OPT_DISKS   },
        { "genre",   1, 0, OPT_GENRE   },
        { "song",    1, 0, OPT_SONG    },
        { "tempo",   1, 0, OPT_TEMPO   },
        { "track",   1, 0, OPT_TRACK   },
        { "tracks",  1, 0, OPT_TRACKS  },
        { "writer",  1, 0, OPT_WRITER  },
        { "year",    1, 0, OPT_YEAR    },
        { NULL,      0, 0, 0 }
    };

    /* Sparse arrays of tag data: some space is wasted, but it's more
       convenient to say tags[OPT_SONG] than to enumerate all the
       metadata types (again) as a struct. */
    char *tags[UCHAR_MAX] = { 0 };
    int nums[UCHAR_MAX] = { 0 };

    /* Any modifications requested? */
    int mods = 0;

    /* Option-processing loop. */
    int c = getopt_long_only(argc, argv, OPT_STRING, long_options, NULL);
    while (c != -1) {
        int r = 2;
        switch(c) {
        /* getopt() returns '?' if there was an error.  It already
           printed the error message, so just return. */
        case '?':
            return 1;

        /* Help and version requests handled here. */
        case OPT_HELP:
            fprintf(stderr, "usage %s %s", argv[0], help_text);
            return 0;
        case OPT_VERSION:
            fprintf(stderr, "%s - %s version %s\n", argv[0], MPEG4IP_PACKAGE,
                    MPEG4IP_VERSION);
            return 0;

        /* Numeric arguments: convert them using sscanf(). */
        case OPT_DISK:
        case OPT_DISKS:
        case OPT_TRACK:
        case OPT_TRACKS:
        case OPT_TEMPO:
            r = sscanf(optarg, "%d", &nums[c]);
            if (r < 1) {
                fprintf(stderr, "%s: option requires numeric argument -- %c\n",
                        argv[0], c);
                return 2;
            }
        /* Break not, lest ye be broken.  :) */
        /* All arguments: all valid options end up here, and we just
           stuff the string pointer into the tags[] array. */
        default:
            tags[c] = optarg;
            mods++;
        } /* end switch */

        c = getopt_long_only(argc, argv, OPT_STRING, long_options, NULL);
    } /* end while */

    /* Check that we have at least one non-option argument */
    if ((argc - optind) < 1) {
        fprintf(stderr,
                "%s: You must specify at least one MP4 file.\n",
                argv[0]);
        fprintf(stderr, "usage %s %s", argv[0], help_text);
        return 3;
    }

    /* Check that we have at least one requested modification.  Probably
       it's useful instead to print the metadata if no modifications are
       requested? */
    if (!mods) {
        fprintf(stderr,
                "%s: You must specify at least one tag modification.\n",
                argv[0]);
        fprintf(stderr, "usage %s %s", argv[0], help_text);
        return 4;
    }

    /* Loop through the non-option arguments, and modify the tags as
       requested. */
    while (optind < argc) {
        char *mp4 = argv[optind++];

        MP4FileHandle h = MP4Modify(mp4);
        if (h == MP4_INVALID_FILE_HANDLE) {
            fprintf(stderr, "Could not open '%s'... aborting\n", mp4);
            return 5;
        }

        /* Track/disk numbers need to be set all at once, but we'd like to
           allow users to just specify -T 12 to indicate that all existing
           track numbers are out of 12.  This means we need to look up the
           current info if it is not being set. */
        uint16_t n0, m0, n1, m1;

        if (tags[OPT_TRACK] || tags[OPT_TRACKS]) {
            MP4GetMetadataTrack(h, &n0, &m0);
            n1 = tags[OPT_TRACK]? nums[OPT_TRACK] : n0;
            m1 = tags[OPT_TRACKS]? nums[OPT_TRACKS] : m0;
            MP4SetMetadataTrack(h, n1, m1);
        }
        if (tags[OPT_DISK] || tags[OPT_DISKS]) {
            MP4GetMetadataDisk(h, &n0, &m0);
            n1 = tags[OPT_DISK]? nums[OPT_DISK] : n0;
            m1 = tags[OPT_DISKS]? nums[OPT_DISKS] : m0;
            MP4SetMetadataDisk(h, n1, m1);
        }

        /* Set the other relevant attributes */
        for (int i = 0;  i < UCHAR_MAX;  i++) {
            if (tags[i]) {
                switch(i) {
                case OPT_ALBUM:
                    MP4SetMetadataAlbum(h, tags[i]);
                    break;
                case OPT_ARTIST:
                    MP4SetMetadataArtist(h, tags[i]);
                    break;
                case OPT_COMMENT:
                    MP4SetMetadataComment(h, tags[i]);
                    break;
                case OPT_GENRE:
                    MP4SetMetadataGenre(h, tags[i]);
                    break;
                case OPT_SONG:
                    MP4SetMetadataName(h, tags[i]);
                    break;
                case OPT_WRITER:
                    MP4SetMetadataWriter(h, tags[i]);
                    break;
                case OPT_YEAR:
                    MP4SetMetadataYear(h, tags[i]);
                    break;
                case OPT_TEMPO:
                    MP4SetMetadataTempo(h, nums[i]);
                    break;
                }
            }
        }
        MP4Close(h);
    } /* end while optind < argc */

    return 0;
}
Exemplo n.º 2
0
DWORD CTag_Mp4::Save(LPCTSTR szFileName)
{
    DWORD dwWin32errorCode = ERROR_SUCCESS;
    if(!m_bEnable)
    {
        return -1;
    }

    char *pFileName = TstrToDataAlloc(szFileName, -1, NULL, DTC_CODE_UTF8);
    if (pFileName == NULL) {
        return -1;
    }
    MP4FileHandle mp4file = MP4Modify(pFileName);
    free(pFileName);
    if(mp4file == MP4_INVALID_FILE_HANDLE)
    {
        return -1;
    }

#ifdef USE_OLD_TAG_API
    if(m_strMetadata_Name.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Name, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataName(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataName(mp4file);
    }

    if(m_strMetadata_Artist.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Artist, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataArtist(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataArtist(mp4file);
    }

    if(m_strMetadata_Album.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Album, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataAlbum(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataAlbum(mp4file);
    }

    if(m_strMetadata_Group.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Group, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataGrouping(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataGrouping(mp4file);
    }

    if(m_strMetadata_Composer.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Composer, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataWriter(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataWriter(mp4file);
    }

    if(m_strMetadata_Genre.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Genre, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataGenre(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataGenre(mp4file);
    }

    if((m_iMetadata_Track1 == -1) && (m_iMetadata_Track2 == -1))
    {
        MP4DeleteMetadataTrack(mp4file);
    }
    else if(m_iMetadata_Track1 == -1)
    {
        MP4SetMetadataTrack(mp4file,0,m_iMetadata_Track2);
    }
    else if(m_iMetadata_Track2 == -1)
    {
        MP4SetMetadataTrack(mp4file,m_iMetadata_Track1,0);
    }
    else
    {
        MP4SetMetadataTrack(mp4file,m_iMetadata_Track1,m_iMetadata_Track2);
    }

    if((m_iMetadata_Disc1 == -1) && (m_iMetadata_Disc2 == -1))
    {
        MP4DeleteMetadataDisk(mp4file);
    }
    else if(m_iMetadata_Disc1 == -1)
    {
        MP4SetMetadataDisk(mp4file,0,m_iMetadata_Disc2);
    }
    else if(m_iMetadata_Disc2 == -1)
    {
        MP4SetMetadataDisk(mp4file,m_iMetadata_Disc1,0);
    }
    else
    {
        MP4SetMetadataDisk(mp4file,m_iMetadata_Disc1,m_iMetadata_Disc2);
    }

    if(m_iMetadata_Tempo == -1)
    {
        MP4DeleteMetadataTempo(mp4file);
    }
    else
    {
        MP4SetMetadataTempo(mp4file,m_iMetadata_Tempo);
    }

    if(m_strMetadata_Year.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Year, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataYear(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataYear(mp4file);
    }

    if(m_iMetadata_Compilation != -1)
    {
        MP4SetMetadataCompilation(mp4file,1);
    }
    else
    {
        MP4DeleteMetadataCompilation(mp4file);
    }

    if(m_strMetadata_Comment.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Comment, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataComment(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataComment(mp4file);
    }

    if(m_strMetadata_Tool.GetLength())
    {
        char *buf = TstrToDataAlloc(m_strMetadata_Tool, -1, NULL, DTC_CODE_UTF8);
        if (buf != NULL) {
            MP4SetMetadataTool(mp4file,buf);
            free(buf);
        }
    }
    else
    {
        MP4DeleteMetadataTool(mp4file);
    }
#else
    const MP4Tags* tags = MP4TagsAlloc();

    if(tags)
    {
        MP4TagsFetch(tags, mp4file);

        if(m_strMetadata_Name.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Name, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetName(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetName(tags, NULL);
        }

        if(m_strMetadata_Artist.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Artist, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetArtist(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetArtist(tags, NULL);
        }

        if(m_strMetadata_Album.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Album, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetAlbum(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetAlbum(tags, NULL);
        }

        if(m_strMetadata_Group.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Group, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetGrouping(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetGrouping(tags, NULL);
        }

        if(m_strMetadata_Composer.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Composer, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetComposer(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetComposer(tags, NULL);
        }

        if(m_strMetadata_Genre.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Genre, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetGenre(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetGenre(tags, NULL);
        }

        if((m_iMetadata_Track1 == -1) && (m_iMetadata_Track2 == -1))
        {
            MP4TagsSetTrack(tags, NULL);
        }
        else
        {
            MP4TagTrack track;
            track.index = (m_iMetadata_Track1 == -1) ? 0 : m_iMetadata_Track1;
            track.total = (m_iMetadata_Track2 == -1) ? 0 : m_iMetadata_Track2;
            MP4TagsSetTrack(tags, &track);
        }

        if((m_iMetadata_Disc1 == -1) && (m_iMetadata_Disc2 == -1))
        {
            MP4TagsSetDisk(tags, NULL);
        }
        else
        {
            MP4TagDisk disk;
            disk.index = (m_iMetadata_Disc1 == -1) ? 0 : m_iMetadata_Disc1;
            disk.total = (m_iMetadata_Disc2 == -1) ? 0 : m_iMetadata_Disc2;
            MP4TagsSetDisk(tags, &disk);
        }

        if(m_iMetadata_Tempo == -1)
        {
            MP4TagsSetTempo(tags, NULL);
        }
        else
        {
            uint16_t tempo = m_iMetadata_Tempo;
            MP4TagsSetTempo(tags, &tempo);
        }

        if(m_strMetadata_Year.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Year, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetReleaseDate(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetReleaseDate(tags, NULL);
        }

        if(m_iMetadata_Compilation != -1)
        {
            uint8_t compilation = 1;
            MP4TagsSetCompilation(tags, &compilation);
        }
        else
        {
            MP4TagsSetCompilation(tags, NULL);
        }

        if(m_strMetadata_Comment.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Comment, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetComments(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetComments(tags, NULL);
        }

        if(m_strMetadata_Tool.GetLength())
        {
            char *buf = TstrToDataAlloc(m_strMetadata_Tool, -1, NULL, DTC_CODE_UTF8);
            if (buf != NULL) {
                MP4TagsSetEncodingTool(tags, buf);
                free(buf);
            }
        }
        else
        {
            MP4TagsSetEncodingTool(tags, NULL);
        }

        MP4TagsStore(tags, mp4file);
        MP4TagsFree(tags);
    }
#endif

    MP4Close(mp4file);

    return dwWin32errorCode;
}
Exemplo n.º 3
0
int mp4_set_metadata(MP4FileHandle file, const char *item, const char *val)
{
    if (!item || (item && !*item) || !val || (val && !*val)) return 0;

    if (!stricmp(item, "track") || !stricmp(item, "tracknumber"))
    {
        unsigned __int16 trkn, tot;
        int t1 = 0, t2 = 0;
        sscanf(val, "%d/%d", &t1, &t2);
        trkn = t1, tot = t2;
        if (!trkn) return 1;
        if (MP4SetMetadataTrack(file, trkn, tot)) return 1;
    }
    else if (!stricmp(item, "disc") || !stricmp(item, "disknumber"))
    {
        unsigned __int16 disk, tot;
        int t1 = 0, t2 = 0;
        sscanf(val, "%d/%d", &t1, &t2);
        disk = t1, tot = t2;
        if (!disk) return 1;
        if (MP4SetMetadataDisk(file, disk, tot)) return 1;
    }
    else if (!stricmp(item, "compilation"))
    {
        unsigned __int8 cpil = atoi(val);
        if (!cpil) return 1;
        if (MP4SetMetadataCompilation(file, cpil)) return 1;
    }
    else if (!stricmp(item, "tempo"))
    {
        unsigned __int16 tempo = atoi(val);
        if (!tempo) return 1;
        if (MP4SetMetadataTempo(file, tempo)) return 1;
    }
    else if (!stricmp(item, "artist"))
    {
        if (MP4SetMetadataArtist(file, val)) return 1;
    }
    else if (!stricmp(item, "writer"))
    {
        if (MP4SetMetadataWriter(file, val)) return 1;
    }
    else if (!stricmp(item, "title"))
    {
        if (MP4SetMetadataName(file, val)) return 1;
    }
    else if (!stricmp(item, "album"))
    {
        if (MP4SetMetadataAlbum(file, val)) return 1;
    }
    else if (!stricmp(item, "date") || !stricmp(item, "year"))
    {
        if (MP4SetMetadataYear(file, val)) return 1;
    }
    else if (!stricmp(item, "comment"))
    {
        if (MP4SetMetadataComment(file, val)) return 1;
    }
    else if (!stricmp(item, "genre"))
    {
        if (MP4SetMetadataGenre(file, val)) return 1;
    }
    else if (!stricmp(item, "tool"))
    {
        if (MP4SetMetadataTool(file, val)) return 1;
    }
    else
    {
        if (MP4SetMetadataFreeForm(file, (char *)item, (u_int8_t *)val, (u_int32_t)strlen(val) + 1)) return 1;
    }

    return 0;
}
Exemplo n.º 4
0
bool MP4::File::save()
{
    MP4Close(mp4file);

    MP4FileHandle handle = MP4Modify(name());
    if(handle == MP4_INVALID_FILE_HANDLE)
    {
        mp4file = MP4Read(name());
        return false;
    }

#ifdef MP4V2_HAS_WRITE_BUG
    /* according to gtkpod we have to delete all meta data before modifying it,
       save the stuff we would not touch */

    // need to fetch/rewrite this only if we aren't going to anyway
    uint8_t compilation = 0;
    bool has_compilation = mp4tag->compilation() == MP4::Tag::Undefined ? MP4GetMetadataCompilation(handle, &compilation) : false;

    char *tool = NULL;
    MP4GetMetadataTool(handle, &tool);

    MP4MetadataDelete(handle);
#endif



#define setmeta(val, tag) \
    if(mp4tag->val().isNull()) { \
        /*MP4DeleteMetadata##tag(handle);*/ \
        MP4SetMetadata##tag(handle, ""); \
    } else { \
        MP4SetMetadata##tag(handle, mp4tag->val().toCString(true)); \
    }

    setmeta(title, Name);
    setmeta(artist, Artist);
    setmeta(album, Album);
    setmeta(comment, Comment);
    setmeta(genre, Genre);

    char buf[100] = "";
    if(mp4tag->year())
        snprintf(buf, sizeof(buf), "%u", mp4tag->year());
    MP4SetMetadataYear(handle, buf);
    u_int16_t t1, t2;
    MP4GetMetadataTrack(handle, &t1, &t2);
    MP4SetMetadataTrack(handle, mp4tag->track(), t2);
    if(mp4tag->bpm() != 0)
        MP4SetMetadataTempo(handle, mp4tag->bpm());
    if(mp4tag->compilation() != MP4::Tag::Undefined) {
        MP4SetMetadataCompilation(handle, mp4tag->compilation());
    }

    MP4SetMetadataCoverArt(handle, mp4tag->cover().size() ? const_cast<u_int8_t *>( reinterpret_cast<const u_int8_t *>( mp4tag->cover().data() ) ) : 0, mp4tag->cover().size());

#ifdef MP4V2_HAS_WRITE_BUG
    // set the saved data again

    if(has_compilation)
        MP4SetMetadataCompilation(handle, compilation);
    if(tool)
    {
        MP4SetMetadataTool(handle, tool);
        free(tool);
    }
#endif

    MP4Close(handle);

    mp4file = MP4Read(name());
    if(mp4file == MP4_INVALID_FILE_HANDLE)
    {
        fprintf(stderr, "reopen failed\n");
        return false;
    }

    return true;
}