📄 mp4creator.cpp
字号:
fprintf(stderr, "%s: extract and delete operations must be done separately\n", ProgName); exit(EXIT_COMMAND_LINE); } // end processing of command line if (doList) { // just want the track listing char* info = MP4FileInfo(mp4FileName); if (!info) { fprintf(stderr, "%s: can't open %s\n", ProgName, mp4FileName); exit(EXIT_INFO); } fputs(info, stdout); free(info); exit(EXIT_SUCCESS); } // test if mp4 file exists bool mp4FileExists = (access(mp4FileName, F_OK) == 0); MP4FileHandle mp4File; if (doCreate || doHint) { if (!mp4FileExists) { if (doCreate) { const char* extension = strrchr(inputFileName, '.'); if (extension == NULL) { fprintf(stderr, "%s: unknown file type: %s: file has no extension\n", ProgName, inputFileName); exit(EXIT_COMMAND_LINE); } if ((!strcmp(extension, ".amr")) || (!strcmp(extension, ".263"))) { mp4File = MP4CreateEx(mp4FileName, Verbosity, createFlags, 1, // add ftyp atom 0, // don't add iods p3gppSupportedBrands[0], 0x0001, p3gppSupportedBrands, sizeof(p3gppSupportedBrands) / sizeof(p3gppSupportedBrands[0])); } else { mp4File = MP4Create(mp4FileName, Verbosity, createFlags); } if (mp4File) { MP4SetTimeScale(mp4File, Mp4TimeScale); } } else if (doEncrypt) { fprintf(stderr, "%s: can't encrypt track in file that doesn't exist\n", ProgName); exit(EXIT_CREATE_FILE); } else { fprintf(stderr, "%s: can't hint track in file that doesn't exist\n", ProgName); exit(EXIT_CREATE_FILE); } } else { if (createFlags != 0) { fprintf(stderr, "Must specify 64 bits on new file only"); exit(EXIT_CREATE_FILE); } mp4File = MP4Modify(mp4FileName, Verbosity); } if (!mp4File) { // mp4 library should have printed a message exit(EXIT_CREATE_FILE); } bool allMpeg4Streams = true; if (doCreate) { MP4TrackId* pCreatedTrackIds = CreateMediaTracks(mp4File, inputFileName, doEncrypt); if (pCreatedTrackIds == NULL) { MP4Close(mp4File); exit(EXIT_CREATE_MEDIA); } // decide if we can raise the ISMA compliance tag in SDP // we do this if audio and/or video are MPEG-4 MP4TrackId* pTrackId = pCreatedTrackIds; while (*pTrackId != MP4_INVALID_TRACK_ID) { const char *type = MP4GetTrackType(mp4File, *pTrackId); // look for objectTypeId (GetTrackEsdsObjectTypeId) uint64_t temp; newverbosity = Verbosity & ~(MP4_DETAILS_ERROR); MP4SetVerbosity(mp4File, newverbosity); bool ret = MP4GetTrackIntegerProperty(mp4File, *pTrackId, "mdia.minf.stbl.stsd.*.esds.decConfigDescr.objectTypeId", &temp); MP4SetVerbosity(mp4File, Verbosity); if (ret) { if (!strcmp(type, MP4_AUDIO_TRACK_TYPE)) { allMpeg4Streams &= (MP4GetTrackEsdsObjectTypeId(mp4File, *pTrackId) == MP4_MPEG4_AUDIO_TYPE); } else if (!strcmp(type, MP4_VIDEO_TRACK_TYPE)) { allMpeg4Streams &= (MP4GetTrackEsdsObjectTypeId(mp4File, *pTrackId) == MP4_MPEG4_VIDEO_TYPE); } } pTrackId++; } if (doHint) { pTrackId = pCreatedTrackIds; while (*pTrackId != MP4_INVALID_TRACK_ID) { CreateHintTrack(mp4File, *pTrackId, payloadName, doInterleave, maxPayloadSize, doEncrypt); pTrackId++; } } } else if (doHint) { // in this case, we only hint the track specified in the command line CreateHintTrack(mp4File, hintTrackId, payloadName, doInterleave, maxPayloadSize, doEncrypt); uint32_t trackNum; trackNum = MP4GetNumberOfTracks(mp4File); for (uint32_t ix = 0; ix < trackNum; ix++) { MP4TrackId trackId = MP4FindTrackId(mp4File, ix); const char *type = MP4GetTrackType(mp4File, trackId); uint64_t temp; if (MP4GetTrackIntegerProperty(mp4File, trackId, "mdia.minf.stbl.stsd.*.esds.decConfigDescr.objectTypeId", &temp)) { if (!strcmp(type, MP4_AUDIO_TRACK_TYPE)) { newverbosity = Verbosity & ~(MP4_DETAILS_ERROR); MP4SetVerbosity(mp4File, newverbosity); allMpeg4Streams &= (MP4GetTrackEsdsObjectTypeId(mp4File, trackId) == MP4_MPEG4_AUDIO_TYPE); MP4SetVerbosity(mp4File, Verbosity); } else if (!strcmp(type, MP4_VIDEO_TRACK_TYPE)) { newverbosity = Verbosity & ~(MP4_DETAILS_ERROR); MP4SetVerbosity(mp4File, newverbosity); allMpeg4Streams &= (MP4GetTrackEsdsObjectTypeId(mp4File, trackId) == MP4_MPEG4_VIDEO_TYPE); MP4SetVerbosity(mp4File, Verbosity); } } } } char *buffer; char *value; newverbosity = Verbosity & ~(MP4_DETAILS_ERROR); MP4SetVerbosity(mp4File, newverbosity); bool retval = MP4GetMetadataTool(mp4File, &value); MP4SetVerbosity(mp4File, Verbosity); if (retval && value != NULL) { if (strncasecmp("mp4creator", value, strlen("mp4creator")) != 0) { buffer = (char *)malloc(strlen(value) + 80); sprintf(buffer, "%s mp4creator %s", value, MPEG4IP_VERSION); MP4SetMetadataTool(mp4File, buffer); free(buffer); } } else { buffer = (char *)malloc(80); sprintf(buffer, "mp4creator %s", MPEG4IP_VERSION); MP4SetMetadataTool(mp4File, buffer); } bool is3GPP = Is3GPP(mp4File); MP4Close(mp4File); if (is3GPP || (force3GPCompliance)) { // If we created the file, CreateEX already takes care of this... MP4Make3GPCompliant(mp4FileName, Verbosity, p3gppSupportedBrands[0], 0x0001, p3gppSupportedBrands, sizeof(p3gppSupportedBrands) / sizeof(p3gppSupportedBrands[0])); } } else if (doEncrypt) { // just encrypting, not creating nor hinting, but may already be hinted if (!mp4FileExists) { fprintf(stderr, "%s: can't encrypt track in file that doesn't exist\n", ProgName); exit(EXIT_CREATE_FILE); } mp4File = MP4Read(mp4FileName, Verbosity); if (!mp4File) { // mp4 library should have printed a message exit(EXIT_CREATE_FILE); } char tempName[PATH_MAX]; if (outputFileName == NULL) { snprintf(tempName, sizeof(tempName), "enc-%s", mp4FileName); outputFileName = tempName; } MP4FileHandle outputFile = MP4CreateEx(outputFileName, Verbosity, createFlags, true, true); MP4SetTimeScale(outputFile, Mp4TimeScale); u_int32_t numTracks = MP4GetNumberOfTracks(mp4File); for (u_int32_t i = 0; i < numTracks; i++) { MP4TrackId curTrackId = MP4FindTrackId(mp4File, i); const char *type = MP4GetTrackType(mp4File, curTrackId); // encrypt only the specified track // if no track was specified in the command-line, encrypt all // audio and video tracks // hint tracks are removed, so need to rehint afterwards // if the track is already encrypted, just copy it if (((curTrackId == encryptTrackId) || ((encryptTrackId == MP4_INVALID_TRACK_ID) && !strcmp(type, MP4_AUDIO_TRACK_TYPE)) || ((encryptTrackId == MP4_INVALID_TRACK_ID) && !strcmp(type, MP4_VIDEO_TRACK_TYPE))) && !(MP4IsIsmaCrypMediaTrack(mp4File,curTrackId))){ ismacryp_session_id_t ismaCrypSId; ismacryp_keytype_t key_type; if ( !strcmp(type, MP4_VIDEO_TRACK_TYPE) ) { key_type = KeyTypeVideo; } else { if ( !strcmp(type, MP4_AUDIO_TRACK_TYPE) ) key_type = KeyTypeAudio; else key_type = KeyTypeOther; } if (ismacrypInitSession(&ismaCrypSId, key_type) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not initialize the ISMAcryp session\n", ProgName); exit(EXIT_ISMACRYP_INIT); } mp4v2_ismacrypParams *icPp = (mp4v2_ismacrypParams *) malloc(sizeof(mp4v2_ismacrypParams)); memset(icPp, 0, sizeof(mp4v2_ismacrypParams)); if (ismacrypGetScheme(ismaCrypSId, &(icPp->scheme_type)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme type. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); exit(EXIT_ISMACRYP_END); } if (ismacrypGetSchemeVersion(ismaCrypSId, &(icPp->scheme_version)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp scheme ver. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); exit(EXIT_ISMACRYP_END); } if (ismacrypGetKMSUri(ismaCrypSId, &(icPp->kms_uri)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp kms uri. sid %d\n", ProgName, ismaCrypSId); CHECK_AND_FREE(icPp->kms_uri); ismacrypEndSession(ismaCrypSId); exit(EXIT_ISMACRYP_END); } if ( ismacrypGetSelectiveEncryption(ismaCrypSId, &(icPp->selective_enc)) != ismacryp_rc_ok ) { fprintf(stderr, "%s: could not get ismacryp selec enc. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); exit(EXIT_ISMACRYP_END); } if (ismacrypGetKeyIndicatorLength(ismaCrypSId, &(icPp->key_ind_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp key ind len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); exit(EXIT_ISMACRYP_END); } if (ismacrypGetIVLength(ismaCrypSId, &(icPp->iv_len)) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not get ismacryp iv len. sid %d\n", ProgName, ismaCrypSId); ismacrypEndSession(ismaCrypSId); exit(EXIT_ISMACRYP_END); } //MP4EncAndCopyTrack(mp4File, curTrackId, ismaCrypSId, outputFile); MP4EncAndCopyTrack(mp4File, curTrackId, icPp, ismacrypEncryptSampleAddHeader2, (u_int32_t) ismaCrypSId, outputFile); if (ismacrypEndSession(ismaCrypSId) != ismacryp_rc_ok) { fprintf(stderr, "%s: could not end the ISMAcryp session\n", ProgName); exit(EXIT_ISMACRYP_END); } } else { MP4CopyTrack(mp4File, curTrackId, outputFile); } } MP4Close(mp4File); MP4Close(outputFile); } else if (doExtract) { if (!mp4FileExists) { fprintf(stderr, "%s: can't extract track in file that doesn't exist\n", ProgName); exit(EXIT_CREATE_FILE); } mp4File = MP4Read(mp4FileName, Verbosity); if (!mp4File) { // mp4 library should have printed a message exit(EXIT_CREATE_FILE); } char tempName[PATH_MAX]; if (outputFileName == NULL) { snprintf(tempName, sizeof(tempName), "%s.t%u", mp4FileName, extractTrackId); outputFileName = tempName; } ExtractTrack(mp4File, extractTrackId, outputFileName); MP4Close(mp4File); } else if (doDelete) { if (!mp4FileExists) { fprintf(stderr, "%s: can't delete track in file that doesn't exist\n", ProgName); exit(EXIT_CREATE_FILE); } mp4File = MP4Modify(mp4FileName, Verbosity); if (!mp4File) { // mp4 library should have printed a message exit(EXIT_CREATE_FILE); } MP4DeleteTrack(mp4File, deleteTrackId); MP4Close(mp4File); doOptimize = true; // to purge unreferenced track data } if (doIsma) { MP4MakeIsmaCompliant(mp4FileName, Verbosity); } if (doOptimize) { if (!MP4Optimize(mp4FileName, NULL, Verbosity)) { // mp4 library should have printed a message exit(EXIT_OPTIMIZE_FILE); } } return(EXIT_SUCCESS);}MP4TrackId* CreateMediaTracks(MP4FileHandle mp4File, const char* inputFileName, bool doEncrypt){ FILE* inFile = fopen(inputFileName, "rb"); if (inFile == NULL) { fprintf(stderr, "%s: can't open file %s: %s\n", ProgName, inputFileName, strerror(errno)); return NULL; } struct stat s; if (fstat(fileno(inFile), &s) < 0) { fprintf(stderr, "%s: can't stat file %s: %s\n", ProgName, inputFileName, strerror(errno)); return NULL; } if (s.st_size == 0) { fprintf(stderr, "%s: file %s is empty\n", ProgName, inputFileName); return NULL; } const char* extension = strrchr(inputFileName, '.'); if (extension == NULL) { fprintf(stderr, "%s: no file type extension\n", ProgName); return NULL; } static MP4TrackId trackIds[2] = { MP4_INVALID_TRACK_ID, MP4_INVALID_TRACK_ID }; MP4TrackId* pTrackIds = trackIds; if (!strcasecmp(extension, ".avi")) { fclose(inFile); inFile = NULL; if (allowAvi) { fprintf(stderr, "You are creating an mp4 file from an avi file\n" "This is not recommended due to the use of b-frames\n"); pTrackIds = AviCreator(mp4File, inputFileName, doEncrypt); } else { fprintf(stderr, "Creating with an avi file is not recommended.\n" "Use avi2raw on the audio and video parts of the avi file,\n" "Then use mp4creator with the extracted files\n" "Use avidump to find the video frame rate\n" "Alternatively, use the --allow-avi-files option\n"); exit(-1); } } else if (!strcasecmp(extension, ".aac")) { trackIds[0] = AacCreator(mp4File, inFile, doEncrypt); } else if (!strcasecmp(extension, ".mp3") || !strcasecmp(extension, ".mp1") || !strcasecmp(extension, ".mp2")) { trackIds[0] = Mp3Creator(mp4File, inFile, doEncrypt); } else if (!strcasecmp(extension, ".divx") || !strcasecmp(extension, ".mp4v") || !strcasecmp(extension, ".m4v") || !strcasecmp(extension, ".xvid") || !strcasecmp(extension, ".cmp")) { trackIds[0] = Mp4vCreator(mp4File, inFile, doEncrypt, allowVariableFrameRate); } else if ((strcasecmp(extension, ".mpg") == 0) || (strcasecmp(extension, ".mpeg") == 0)) { fclose(inFile); inFile = NULL; pTrackIds = MpegCreator(mp4File, inputFileName, doEncrypt); } else if (strcasecmp(extension, ".amr") == 0) { trackIds[0] = AmrCreator(mp4File, inFile, false); } else if (strcasecmp(extension, ".263") == 0) { trackIds[0] = H263Creator(mp4File, inFile, h263Profile, h263Level, setBitrates, H263CbrTolerance); } else if ((strcasecmp(extension, ".h264") == 0) || (strcasecmp(extension, ".264") == 0)) { trackIds[0] = H264Creator(mp4File, inFile); } else { fprintf(stderr, "%s: unknown file extension in %s\n", ProgName, inputFileName); return NULL; } if (inFile) { fclose(inFile); } if (pTrackIds == NULL || pTrackIds[0] == MP4_INVALID_TRACK_ID) { return NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -