📄 mp4creator.cpp
字号:
bool allMpeg4Streams = true; if (doCreate) { MP4TrackId* pCreatedTrackIds = CreateMediaTracks(mp4File, inputFileName); 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); if (!strcmp(type, MP4_AUDIO_TRACK_TYPE)) { allMpeg4Streams &= (MP4GetTrackAudioType(mp4File, *pTrackId) == MP4_MPEG4_AUDIO_TYPE); } else if (!strcmp(type, MP4_VIDEO_TRACK_TYPE)) { allMpeg4Streams &= (MP4GetTrackVideoType(mp4File, *pTrackId) == MP4_MPEG4_VIDEO_TYPE); } pTrackId++; } if (doHint) { MP4TrackId* pTrackId = pCreatedTrackIds; while (*pTrackId != MP4_INVALID_TRACK_ID) { CreateHintTrack(mp4File, *pTrackId, payloadName, doInterleave, maxPayloadSize); pTrackId++; } } } else { CreateHintTrack(mp4File, hintTrackId, payloadName, doInterleave, maxPayloadSize); } MP4Close(mp4File); if (doCreate) { // this creates simple MPEG-4 OD and BIFS streams MP4MakeIsmaCompliant(mp4FileName, Verbosity, allMpeg4Streams); } } 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 (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){ 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; pTrackIds = AviCreator(mp4File, inputFileName); } else if (!strcasecmp(extension, ".aac")) { trackIds[0] = AacCreator(mp4File, inFile); } else if (!strcasecmp(extension, ".mp3") || !strcasecmp(extension, ".mp1") || !strcasecmp(extension, ".mp2")) { trackIds[0] = Mp3Creator(mp4File, inFile); } else if (!strcasecmp(extension, ".divx") || !strcasecmp(extension, ".mp4v") || !strcasecmp(extension, ".m4v") || !strcasecmp(extension, ".xvid") || !strcasecmp(extension, ".cmp")) { trackIds[0] = Mp4vCreator(mp4File, inFile); } else if ((strcasecmp(extension, ".mpg") == 0) || (strcasecmp(extension, ".mpeg") == 0)) { fclose(inFile); inFile = NULL; pTrackIds = MpegCreator(mp4File, inputFileName); } else if (strcasecmp(extension, ".h264") == 0) { trackIds[0] = H264Creator(mp4File, inFile); } else { fprintf(stderr, "%s: unknown file type\n", ProgName); return NULL; } if (inFile) { fclose(inFile); } if (pTrackIds == NULL || pTrackIds[0] == MP4_INVALID_TRACK_ID) { return NULL; } return pTrackIds;}void CreateHintTrack(MP4FileHandle mp4File, MP4TrackId mediaTrackId, const char* payloadName, bool interleave, u_int16_t maxPayloadSize){ bool rc = false; if (MP4GetTrackNumberOfSamples(mp4File, mediaTrackId) == 0) { fprintf(stderr, "%s: couldn't create hint track, no media samples\n", ProgName); MP4Close(mp4File); exit(EXIT_CREATE_HINT); } // vector out to specific hinters const char* trackType = MP4GetTrackType(mp4File, mediaTrackId); if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) { u_int8_t audioType = MP4GetTrackAudioType(mp4File, mediaTrackId); switch (audioType) { case MP4_MPEG4_AUDIO_TYPE: case MP4_MPEG2_AAC_MAIN_AUDIO_TYPE: case MP4_MPEG2_AAC_LC_AUDIO_TYPE: case MP4_MPEG2_AAC_SSR_AUDIO_TYPE: rc = MP4AV_RfcIsmaHinter(mp4File, mediaTrackId, interleave, maxPayloadSize); break; case MP4_MPEG1_AUDIO_TYPE: case MP4_MPEG2_AUDIO_TYPE: if (payloadName && (!strcasecmp(payloadName, "3119") || !strcasecmp(payloadName, "mpa-robust"))) { rc = MP4AV_Rfc3119Hinter(mp4File, mediaTrackId, interleave, maxPayloadSize); } else { rc = MP4AV_Rfc2250Hinter(mp4File, mediaTrackId, false, maxPayloadSize); } break; case MP4_PCM16_BIG_ENDIAN_AUDIO_TYPE: case MP4_PCM16_LITTLE_ENDIAN_AUDIO_TYPE: rc = L16Hinter(mp4File, mediaTrackId, maxPayloadSize); break; default: fprintf(stderr, "%s: can't hint non-MPEG4/non-MP3 audio type\n", ProgName); } } else if (!strcmp(trackType, MP4_VIDEO_TRACK_TYPE)) { u_int8_t videoType = MP4GetTrackVideoType(mp4File, mediaTrackId); switch (videoType) { case MP4_MPEG4_VIDEO_TYPE: rc = MP4AV_Rfc3016Hinter(mp4File, mediaTrackId, maxPayloadSize); break; case MP4_H264_VIDEO_TYPE: rc = MP4AV_H264Hinter(mp4File, mediaTrackId, maxPayloadSize); break; case MP4_MPEG1_VIDEO_TYPE: case MP4_MPEG2_SIMPLE_VIDEO_TYPE: case MP4_MPEG2_MAIN_VIDEO_TYPE: rc = Mpeg12Hinter(mp4File, mediaTrackId, maxPayloadSize); break; default: fprintf(stderr, "%s: can't hint non-MPEG4 video type\n", ProgName); break; } } else { fprintf(stderr, "%s: can't hint track type %s\n", ProgName, trackType); } if (!rc) { fprintf(stderr, "%s: error hinting track %u\n", ProgName, mediaTrackId); MP4Close(mp4File); exit(EXIT_CREATE_HINT); }}void ExtractTrack( MP4FileHandle mp4File, MP4TrackId trackId, const char* outputFileName){ int openFlags = O_WRONLY | O_TRUNC | OPEN_CREAT; int outFd = open(outputFileName, openFlags, 0644); if (outFd == -1) { fprintf(stderr, "%s: can't open %s: %s\n", ProgName, outputFileName, strerror(errno)); exit(EXIT_EXTRACT_TRACK); } // some track types have special needs // to properly recreate their raw ES file bool prependES = false; bool prependADTS = false; const char* trackType = MP4GetTrackType(mp4File, trackId); if (!strcmp(trackType, MP4_VIDEO_TRACK_TYPE)) { if (MP4_IS_MPEG4_VIDEO_TYPE(MP4GetTrackVideoType(mp4File, trackId))) { prependES = true; } } else if (!strcmp(trackType, MP4_AUDIO_TRACK_TYPE)) { if (MP4_IS_AAC_AUDIO_TYPE(MP4GetTrackAudioType(mp4File, trackId))) { prependADTS = true; } } MP4SampleId numSamples = MP4GetTrackNumberOfSamples(mp4File, trackId); u_int8_t* pSample; u_int32_t sampleSize; // extraction loop for (MP4SampleId sampleId = 1 ; sampleId <= numSamples; sampleId++) { int rc; // signal to ReadSample() // that it should malloc a buffer for us pSample = NULL; sampleSize = 0; if (prependADTS) { // need some very specialized work for these MP4AV_AdtsMakeFrameFromMp4Sample( mp4File, trackId, sampleId, &pSample, &sampleSize); } else { // read the sample rc = MP4ReadSample( mp4File, trackId, sampleId, &pSample, &sampleSize); if (rc == 0) { fprintf(stderr, "%s: read sample %u for %s failed\n", ProgName, sampleId, outputFileName); exit(EXIT_EXTRACT_TRACK); } if (prependES && sampleId == 1) { u_int8_t* pConfig = NULL; u_int32_t configSize = 0; MP4GetTrackESConfiguration(mp4File, trackId, &pConfig, &configSize); write(outFd, pConfig, configSize); free(pConfig); } } rc = write(outFd, pSample, sampleSize); if (rc == -1 || (u_int32_t)rc != sampleSize) { fprintf(stderr, "%s: write to %s failed: %s\n", ProgName, outputFileName, strerror(errno)); exit(EXIT_EXTRACT_TRACK); } free(pSample); } // close ES file close(outFd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -