diff --git a/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/Chapter.java b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/Chapter.java
new file mode 100644
index 0000000..bf726ae
--- /dev/null
+++ b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/Chapter.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2021 Taner Sener
+ *
+ * This file is part of FFmpegKit.
+ *
+ * FFmpegKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpegKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with FFmpegKit. If not, see .
+ */
+
+package com.arthenica.ffmpegkit;
+
+import org.json.JSONObject;
+
+public class Chapter {
+
+ /* KEYS */
+ public static final String KEY_ID = "id";
+ public static final String KEY_TIME_BASE = "time_base";
+ public static final String KEY_START = "start";
+ public static final String KEY_START_TIME = "start_time";
+ public static final String KEY_END = "end";
+ public static final String KEY_END_TIME = "end_time";
+ public static final String KEY_TAGS = "tags";
+
+ private final JSONObject jsonObject;
+
+ public Chapter(JSONObject jsonObject) {
+ this.jsonObject = jsonObject;
+ }
+
+ public Long getId() {
+ return getNumberProperty(KEY_ID);
+ }
+
+ public String getTimeBase() {
+ return getStringProperty(KEY_TIME_BASE);
+ }
+
+ public Long getStart() {
+ return getNumberProperty(KEY_START);
+ }
+
+ public String getStartTime() {
+ return getStringProperty(KEY_START_TIME);
+ }
+
+ public Long getEnd() {
+ return getNumberProperty(KEY_END);
+ }
+
+ public String getEndTime() {
+ return getStringProperty(KEY_END_TIME);
+ }
+
+ public JSONObject getTags() {
+ return getProperties(KEY_TAGS);
+ }
+
+ /**
+ * Returns the chapter property associated with the key.
+ *
+ * @param key property key
+ * @return chapter property as string or null if the key is not found
+ */
+ public String getStringProperty(final String key) {
+ JSONObject chapterProperties = getAllProperties();
+ if (chapterProperties == null) {
+ return null;
+ }
+
+ if (chapterProperties.has(key)) {
+ return chapterProperties.optString(key);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the chapter property associated with the key.
+ *
+ * @param key property key
+ * @return chapter property as Long or null if the key is not found
+ */
+ public Long getNumberProperty(String key) {
+ JSONObject chapterProperties = getAllProperties();
+ if (chapterProperties == null) {
+ return null;
+ }
+
+ if (chapterProperties.has(key)) {
+ return chapterProperties.optLong(key);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the chapter properties associated with the key.
+ *
+ * @param key properties key
+ * @return chapter properties as a JSONObject or null if the key is not found
+ */
+ public JSONObject getProperties(String key) {
+ JSONObject chapterProperties = getAllProperties();
+ if (chapterProperties == null) {
+ return null;
+ }
+
+ return chapterProperties.optJSONObject(key);
+ }
+
+ /**
+ * Returns all chapter properties defined.
+ *
+ * @return all chapter properties as a JSONObject or null if no properties are defined
+ */
+ public JSONObject getAllProperties() {
+ return jsonObject;
+ }
+
+}
diff --git a/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFprobeKit.java b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFprobeKit.java
index 2854287..9b9a6a3 100644
--- a/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFprobeKit.java
+++ b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFprobeKit.java
@@ -52,6 +52,16 @@ public class FFprobeKit {
private FFprobeKit() {
}
+ /**
+ *
Builds the default command used to get media information for a file.
+ *
+ * @param path file path to use in the command
+ * @return default command arguments to get media information
+ */
+ private static String[] defaultGetMediaInformationCommandArguments(final String path) {
+ return new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-show_chapters", "-i", path};
+ }
+
/**
*
Synchronously executes FFprobe with arguments provided.
*
@@ -249,7 +259,7 @@ public class FFprobeKit {
* @return media information session created for this execution
*/
public static MediaInformationSession getMediaInformation(final String path) {
- final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path});
+ final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path));
FFmpegKitConfig.getMediaInformationExecute(session, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@@ -265,7 +275,7 @@ public class FFprobeKit {
*/
public static MediaInformationSession getMediaInformation(final String path,
final int waitTimeout) {
- final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path});
+ final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path));
FFmpegKitConfig.getMediaInformationExecute(session, waitTimeout);
@@ -284,7 +294,7 @@ public class FFprobeKit {
*/
public static MediaInformationSession getMediaInformationAsync(final String path,
final ExecuteCallback executeCallback) {
- final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path}, executeCallback);
+ final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), executeCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@@ -307,7 +317,7 @@ public class FFprobeKit {
final ExecuteCallback executeCallback,
final LogCallback logCallback,
final int waitTimeout) {
- final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path}, executeCallback, logCallback);
+ final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), executeCallback, logCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, waitTimeout);
@@ -328,7 +338,7 @@ public class FFprobeKit {
public static MediaInformationSession getMediaInformationAsync(final String path,
final ExecuteCallback executeCallback,
final ExecutorService executorService) {
- final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path}, executeCallback);
+ final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), executeCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, executorService, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@@ -353,7 +363,7 @@ public class FFprobeKit {
final LogCallback logCallback,
final ExecutorService executorService,
final int waitTimeout) {
- final MediaInformationSession session = new MediaInformationSession(new String[]{"-v", "error", "-hide_banner", "-print_format", "json", "-show_format", "-show_streams", "-i", path}, executeCallback, logCallback);
+ final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), executeCallback, logCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, executorService, waitTimeout);
diff --git a/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformation.java b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformation.java
index 83d04a3..faf6674 100644
--- a/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformation.java
+++ b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformation.java
@@ -49,9 +49,15 @@ public class MediaInformation {
*/
private final List streams;
- public MediaInformation(final JSONObject jsonObject, final List streams) {
+ /**
+ * Stores chapters.
+ */
+ private final List chapters;
+
+ public MediaInformation(final JSONObject jsonObject, final List streams, final List chapters) {
this.jsonObject = jsonObject;
this.streams = streams;
+ this.chapters = chapters;
}
/**
@@ -135,6 +141,15 @@ public class MediaInformation {
return streams;
}
+ /**
+ * Returns all chapters.
+ *
+ * @return list of chapters
+ */
+ public List getChapters() {
+ return chapters;
+ }
+
/**
* Returns the media property associated with the key.
*
diff --git a/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformationJsonParser.java b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformationJsonParser.java
index 2d78e6c..45a9471 100644
--- a/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformationJsonParser.java
+++ b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformationJsonParser.java
@@ -34,6 +34,9 @@ import java.util.ArrayList;
*/
public class MediaInformationJsonParser {
+ public static final String KEY_STREAMS = "streams";
+ public static final String KEY_CHAPTERS = "chapters";
+
/**
* Extracts MediaInformation
from the given FFprobe json output. Note that this
* method does not throw {@link JSONException} as {@link #fromWithError(String)} does and
@@ -59,18 +62,27 @@ public class MediaInformationJsonParser {
* @throws JSONException if a parsing error occurs
*/
public static MediaInformation fromWithError(final String ffprobeJsonOutput) throws JSONException {
- JSONObject jsonObject = new JSONObject(ffprobeJsonOutput);
- JSONArray streamArray = jsonObject.optJSONArray("streams");
+ final JSONObject jsonObject = new JSONObject(ffprobeJsonOutput);
+ final JSONArray streamArray = jsonObject.optJSONArray(KEY_STREAMS);
+ final JSONArray chapterArray = jsonObject.optJSONArray(KEY_CHAPTERS);
- ArrayList arrayList = new ArrayList<>();
+ ArrayList streamList = new ArrayList<>();
for (int i = 0; streamArray != null && i < streamArray.length(); i++) {
JSONObject streamObject = streamArray.optJSONObject(i);
if (streamObject != null) {
- arrayList.add(new StreamInformation(streamObject));
+ streamList.add(new StreamInformation(streamObject));
+ }
+ }
+
+ ArrayList chapterList = new ArrayList<>();
+ for (int i = 0; chapterArray != null && i < chapterArray.length(); i++) {
+ JSONObject chapterObject = chapterArray.optJSONObject(i);
+ if (chapterObject != null) {
+ chapterList.add(new Chapter(chapterObject));
}
}
- return new MediaInformation(jsonObject, arrayList);
+ return new MediaInformation(jsonObject, streamList, chapterList);
}
}
diff --git a/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/StreamInformation.java b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/StreamInformation.java
index 487de30..45bd329 100644
--- a/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/StreamInformation.java
+++ b/android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/StreamInformation.java
@@ -211,7 +211,7 @@ public class StreamInformation {
/**
* Returns all tags.
*
- * @return tags dictionary
+ * @return tags object
*/
public JSONObject getTags() {
return getProperties(KEY_TAGS);
diff --git a/android/ffmpeg-kit-android-lib/src/test/java/com/arthenica/ffmpegkit/FFmpegKitTest.java b/android/ffmpeg-kit-android-lib/src/test/java/com/arthenica/ffmpegkit/FFmpegKitTest.java
index 24cbba8..29e16ad 100644
--- a/android/ffmpeg-kit-android-lib/src/test/java/com/arthenica/ffmpegkit/FFmpegKitTest.java
+++ b/android/ffmpeg-kit-android-lib/src/test/java/com/arthenica/ffmpegkit/FFmpegKitTest.java
@@ -72,6 +72,85 @@ public class FFmpegKitTest {
" }\n" +
" }\n" +
" ],\n" +
+ " \"chapters\": [\n" +
+ " {\n" +
+ " \"id\": 0,\n" +
+ " \"time_base\": \"1/22050\",\n" +
+ " \"start\": 0,\n" +
+ " \"start_time\": \"0.000000\",\n" +
+ " \"end\": 11158238,\n" +
+ " \"end_time\": \"506.042540\",\n" +
+ " \"tags\": {\n" +
+ " \"title\": \"1 Laying Plans - 2 Waging War\"\n" +
+ " }\n" +
+ " },\n" +
+ " {\n" +
+ " \"id\": 1,\n" +
+ " \"time_base\": \"1/22050\",\n" +
+ " \"start\": 11158238,\n" +
+ " \"start_time\": \"506.042540\",\n" +
+ " \"end\": 21433051,\n" +
+ " \"end_time\": \"972.020454\",\n" +
+ " \"tags\": {\n" +
+ " \"title\": \"3 Attack By Stratagem - 4 Tactical Dispositions\"\n" +
+ " }\n" +
+ " },\n" +
+ " {\n" +
+ " \"id\": 2,\n" +
+ " \"time_base\": \"1/22050\",\n" +
+ " \"start\": 21433051,\n" +
+ " \"start_time\": \"972.020454\",\n" +
+ " \"end\": 35478685,\n" +
+ " \"end_time\": \"1609.010658\",\n" +
+ " \"tags\": {\n" +
+ " \"title\": \"5 Energy - 6 Weak Points and Strong\"\n" +
+ " }\n" +
+ " },\n" +
+ " {\n" +
+ " \"id\": 3,\n" +
+ " \"time_base\": \"1/22050\",\n" +
+ " \"start\": 35478685,\n" +
+ " \"start_time\": \"1609.010658\",\n" +
+ " \"end\": 47187043,\n" +
+ " \"end_time\": \"2140.001950\",\n" +
+ " \"tags\": {\n" +
+ " \"title\": \"7 Maneuvering - 8 Variation in Tactics\"\n" +
+ " }\n" +
+ " },\n" +
+ " {\n" +
+ " \"id\": 4,\n" +
+ " \"time_base\": \"1/22050\",\n" +
+ " \"start\": 47187043,\n" +
+ " \"start_time\": \"2140.001950\",\n" +
+ " \"end\": 66635594,\n" +
+ " \"end_time\": \"3022.022404\",\n" +
+ " \"tags\": {\n" +
+ " \"title\": \"9 The Army on the March - 10 Terrain\"\n" +
+ " }\n" +
+ " },\n" +
+ " {\n" +
+ " \"id\": 5,\n" +
+ " \"time_base\": \"1/22050\",\n" +
+ " \"start\": 66635594,\n" +
+ " \"start_time\": \"3022.022404\",\n" +
+ " \"end\": 83768105,\n" +
+ " \"end_time\": \"3799.007029\",\n" +
+ " \"tags\": {\n" +
+ " \"title\": \"11 The Nine Situations\"\n" +
+ " }\n" +
+ " },\n" +
+ " {\n" +
+ " \"id\": 6,\n" +
+ " \"time_base\": \"1/22050\",\n" +
+ " \"start\": 83768105,\n" +
+ " \"start_time\": \"3799.007029\",\n" +
+ " \"end\": 95659008,\n" +
+ " \"end_time\": \"4338.277007\",\n" +
+ " \"tags\": {\n" +
+ " \"title\": \"12 The Attack By Fire - 13 The Use of Spies\"\n" +
+ " }\n" +
+ " }\n" +
+ " ],\n" +
" \"format\": {\n" +
" \"filename\": \"sample.mp3\",\n" +
" \"nb_streams\": 1,\n" +
@@ -459,6 +538,11 @@ public class FFmpegKitTest {
Assert.assertNotNull(mediaInformation.getStreams());
Assert.assertEquals(1, mediaInformation.getStreams().size());
assertAudioStream(mediaInformation.getStreams().get(0), 0L, "mp3", "MP3 (MPEG audio layer 3)", "44100", "stereo", "fltp", "320000");
+
+ Assert.assertNotNull(mediaInformation.getChapters());
+ Assert.assertEquals(7, mediaInformation.getChapters().size());
+ assertChapter(mediaInformation.getChapters().get(0), 0L, "1/22050", 0L, "0.000000", 11158238L, "506.042540");
+ assertChapter(mediaInformation.getChapters().get(1), 1L, "1/22050", 11158238L, "506.042540", 21433051L, "972.020454");
}
@Test
@@ -743,4 +827,18 @@ public class FFmpegKitTest {
Assert.assertEquals(codecTimeBase, streamInformation.getCodecTimeBase());
}
+ private void assertChapter(Chapter chapter, Long id, String timeBase, Long start, String startTime, Long end, String endTime) {
+ Assert.assertEquals(id, chapter.getId());
+ Assert.assertEquals(timeBase, chapter.getTimeBase());
+
+ Assert.assertEquals(start, chapter.getStart());
+ Assert.assertEquals(startTime, chapter.getStartTime());
+
+ Assert.assertEquals(end, chapter.getEnd());
+ Assert.assertEquals(endTime, chapter.getEndTime());
+
+ Assert.assertNotNull(chapter.getTags());
+ Assert.assertEquals(1, chapter.getTags().length());
+ }
+
}
diff --git a/apple/src/Chapter.h b/apple/src/Chapter.h
new file mode 100644
index 0000000..f85e2b7
--- /dev/null
+++ b/apple/src/Chapter.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2021 Taner Sener
+ *
+ * This file is part of FFmpegKit.
+ *
+ * FFmpegKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpegKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with FFmpegKit. If not, see .
+ */
+
+#ifndef FFMPEG_KIT_CHAPTER_H
+#define FFMPEG_KIT_CHAPTER_H
+
+#import
+
+extern NSString* const ChapterKeyId;
+extern NSString* const ChapterKeyTimeBase;
+extern NSString* const ChapterKeyStart;
+extern NSString* const ChapterKeyStartTime;
+extern NSString* const ChapterKeyEnd;
+extern NSString* const ChapterKeyEndTime;
+extern NSString* const ChapterKeyTags;
+
+/**
+ * Chapter class.
+ */
+@interface Chapter : NSObject
+
+- (instancetype)init:(NSDictionary*)chapterDictionary;
+
+- (NSNumber*)getId;
+
+- (NSString*)getTimeBase;
+
+- (NSNumber*)getStart;
+
+- (NSString*)getStartTime;
+
+- (NSNumber*)getEnd;
+
+- (NSString*)getEndTime;
+
+- (NSDictionary*)getTags;
+
+/**
+ * Returns the chapter property associated with the key.
+ *
+ * @return chapter property as string or nil if the key is not found
+ */
+- (NSString*)getStringProperty:(NSString*)key;
+
+/**
+ * Returns the chapter property associated with the key.
+ *
+ * @return chapter property as number or nil if the key is not found
+ */
+- (NSNumber*)getNumberProperty:(NSString*)key;
+
+/**
+ * Returns the chapter properties associated with the key.
+ *
+ * @return chapter properties in a dictionary or nil if the key is not found
+*/
+- (NSDictionary*)getProperties:(NSString*)key;
+
+/**
+ * Returns all chapter properties defined.
+ *
+ * @return all chapter properties in a dictionary or nil if no properties are defined
+*/
+- (NSDictionary*)getAllProperties;
+
+@end
+
+#endif // FFMPEG_KIT_CHAPTER_H
diff --git a/apple/src/Chapter.m b/apple/src/Chapter.m
new file mode 100644
index 0000000..30baf06
--- /dev/null
+++ b/apple/src/Chapter.m
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2021 Taner Sener
+ *
+ * This file is part of FFmpegKit.
+ *
+ * FFmpegKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpegKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with FFmpegKit. If not, see .
+ */
+
+#import "Chapter.h"
+
+NSString* const ChapterKeyId = @"id";
+NSString* const ChapterKeyTimeBase = @"time_base";
+NSString* const ChapterKeyStart = @"start";
+NSString* const ChapterKeyStartTime = @"start_time";
+NSString* const ChapterKeyEnd = @"end";
+NSString* const ChapterKeyEndTime = @"end_time";
+NSString* const ChapterKeyTags = @"tags";
+
+@implementation Chapter {
+
+ /**
+ * Stores all properties.
+ */
+ NSDictionary *dictionary;
+
+}
+
+- (instancetype)init:(NSDictionary*)chapterDictionary {
+ self = [super init];
+ if (self) {
+ dictionary = chapterDictionary;
+ }
+
+ return self;
+}
+
+- (NSNumber*)getId {
+ return [self getNumberProperty:ChapterKeyId];
+}
+
+- (NSString*)getTimeBase {
+ return [self getStringProperty:ChapterKeyTimeBase];
+}
+
+- (NSNumber*)getStart {
+ return [self getNumberProperty:ChapterKeyStart];
+}
+
+- (NSString*)getStartTime {
+ return [self getStringProperty:ChapterKeyStartTime];
+}
+
+- (NSNumber*)getEnd {
+ return [self getNumberProperty:ChapterKeyEnd];
+}
+
+- (NSString*)getEndTime {
+ return [self getStringProperty:ChapterKeyEndTime];
+}
+
+- (NSDictionary*)getTags {
+ return [self getProperties:ChapterKeyTags];
+}
+
+- (NSString*)getStringProperty:(NSString*)key {
+ NSDictionary* allProperties = [self getAllProperties];
+ if (allProperties == nil) {
+ return nil;
+ }
+
+ return allProperties[key];
+}
+
+- (NSNumber*)getNumberProperty:(NSString*)key {
+ NSDictionary* mediaProperties = [self getAllProperties];
+ if (mediaProperties == nil) {
+ return nil;
+ }
+
+ return mediaProperties[key];
+}
+
+- (NSDictionary*)getProperties:(NSString*)key {
+ NSDictionary* allProperties = [self getAllProperties];
+ if (allProperties == nil) {
+ return nil;
+ }
+
+ return allProperties[key];
+}
+
+- (NSDictionary*)getAllProperties {
+ return dictionary;
+}
+
+@end
diff --git a/apple/src/FFprobeKit.m b/apple/src/FFprobeKit.m
index 6611b0e..cc013ea 100644
--- a/apple/src/FFprobeKit.m
+++ b/apple/src/FFprobeKit.m
@@ -28,6 +28,10 @@
[FFmpegKitConfig class];
}
++ (NSArray*)defaultGetMediaInformationCommandArguments:(NSString*)path {
+ return [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-show_chapters", @"-i", path, nil];
+}
+
+ (FFprobeSession*)executeWithArguments:(NSArray*)arguments {
FFprobeSession* session = [[FFprobeSession alloc] init:arguments];
[FFmpegKitConfig ffprobeExecute:session];
@@ -89,42 +93,42 @@
}
+ (MediaInformationSession*)getMediaInformation:(NSString*)path {
- NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
+ NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments];
[FFmpegKitConfig getMediaInformationExecute:session withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformation:(NSString*)path withTimeout:(int)waitTimeout {
- NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
+ NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments];
[FFmpegKitConfig getMediaInformationExecute:session withTimeout:waitTimeout];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withExecuteCallback:(ExecuteCallback)executeCallback {
- NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
+ NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:executeCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withExecuteCallback:(ExecuteCallback)executeCallback withLogCallback:(LogCallback)logCallback withTimeout:(int)waitTimeout {
- NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
+ NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:executeCallback withLogCallback:logCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session withTimeout:waitTimeout];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withExecuteCallback:(ExecuteCallback)executeCallback onDispatchQueue:(dispatch_queue_t)queue {
- NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
+ NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:executeCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session onDispatchQueue:queue withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withExecuteCallback:(ExecuteCallback)executeCallback withLogCallback:(LogCallback)logCallback onDispatchQueue:(dispatch_queue_t)queue withTimeout:(int)waitTimeout {
- NSArray* arguments = [[NSArray alloc] initWithObjects:@"-v", @"error", @"-hide_banner", @"-print_format", @"json", @"-show_format", @"-show_streams", @"-i", path, nil];
+ NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withExecuteCallback:executeCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session onDispatchQueue:queue withTimeout:waitTimeout];
return session;
diff --git a/apple/src/Makefile.am b/apple/src/Makefile.am
index cdc9009..2a2d6d8 100644
--- a/apple/src/Makefile.am
+++ b/apple/src/Makefile.am
@@ -6,6 +6,7 @@ libffmpegkit_la_SOURCES = \
AbstractSession.m \
ArchDetect.m \
AtomicLong.m \
+ Chapter.m \
FFmpegKit.m \
FFmpegKitConfig.m \
FFmpegSession.m \
@@ -35,6 +36,7 @@ include_HEADERS = \
AbstractSession.h \
ArchDetect.h \
AtomicLong.h \
+ Chapter.h \
ExecuteCallback.h \
FFmpegKit.h \
FFmpegKitConfig.h \
diff --git a/apple/src/Makefile.in b/apple/src/Makefile.in
index d14103d..600e946 100644
--- a/apple/src/Makefile.in
+++ b/apple/src/Makefile.in
@@ -134,18 +134,18 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libffmpegkit_la_DEPENDENCIES =
am__libffmpegkit_la_SOURCES_DIST = AbstractSession.m ArchDetect.m \
- AtomicLong.m FFmpegKit.m FFmpegKitConfig.m FFmpegSession.m \
- FFprobeKit.m FFprobeSession.m Log.m MediaInformation.m \
- MediaInformationJsonParser.m MediaInformationSession.m \
- Packages.m ReturnCode.m Statistics.m StreamInformation.m \
- ffmpegkit_exception.m fftools_cmdutils.c fftools_ffmpeg.c \
- fftools_ffmpeg_filter.c fftools_ffmpeg_hw.c \
+ AtomicLong.m Chapter.m FFmpegKit.m FFmpegKitConfig.m \
+ FFmpegSession.m FFprobeKit.m FFprobeSession.m Log.m \
+ MediaInformation.m MediaInformationJsonParser.m \
+ MediaInformationSession.m Packages.m ReturnCode.m Statistics.m \
+ StreamInformation.m ffmpegkit_exception.m fftools_cmdutils.c \
+ fftools_ffmpeg.c fftools_ffmpeg_filter.c fftools_ffmpeg_hw.c \
fftools_ffmpeg_opt.c fftools_ffprobe.c \
fftools_ffmpeg_videotoolbox.c
@FFMPEGKIT_VIDEOTOOLBOX_TRUE@am__objects_1 = libffmpegkit_la-fftools_ffmpeg_videotoolbox.lo
am_libffmpegkit_la_OBJECTS = libffmpegkit_la-AbstractSession.lo \
libffmpegkit_la-ArchDetect.lo libffmpegkit_la-AtomicLong.lo \
- libffmpegkit_la-FFmpegKit.lo \
+ libffmpegkit_la-Chapter.lo libffmpegkit_la-FFmpegKit.lo \
libffmpegkit_la-FFmpegKitConfig.lo \
libffmpegkit_la-FFmpegSession.lo libffmpegkit_la-FFprobeKit.lo \
libffmpegkit_la-FFprobeSession.lo libffmpegkit_la-Log.lo \
@@ -189,6 +189,7 @@ am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/libffmpegkit_la-AbstractSession.Plo \
./$(DEPDIR)/libffmpegkit_la-ArchDetect.Plo \
./$(DEPDIR)/libffmpegkit_la-AtomicLong.Plo \
+ ./$(DEPDIR)/libffmpegkit_la-Chapter.Plo \
./$(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo \
./$(DEPDIR)/libffmpegkit_la-FFmpegKitConfig.Plo \
./$(DEPDIR)/libffmpegkit_la-FFmpegSession.Plo \
@@ -401,8 +402,8 @@ top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libffmpegkit.la
libffmpegkit_la_LIBADD = @FFMPEG_FRAMEWORKS@
libffmpegkit_la_SOURCES = AbstractSession.m ArchDetect.m AtomicLong.m \
- FFmpegKit.m FFmpegKitConfig.m FFmpegSession.m FFprobeKit.m \
- FFprobeSession.m Log.m MediaInformation.m \
+ Chapter.m FFmpegKit.m FFmpegKitConfig.m FFmpegSession.m \
+ FFprobeKit.m FFprobeSession.m Log.m MediaInformation.m \
MediaInformationJsonParser.m MediaInformationSession.m \
Packages.m ReturnCode.m Statistics.m StreamInformation.m \
ffmpegkit_exception.m fftools_cmdutils.c fftools_ffmpeg.c \
@@ -412,6 +413,7 @@ include_HEADERS = \
AbstractSession.h \
ArchDetect.h \
AtomicLong.h \
+ Chapter.h \
ExecuteCallback.h \
FFmpegKit.h \
FFmpegKitConfig.h \
@@ -521,6 +523,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-AbstractSession.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-ArchDetect.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-AtomicLong.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-Chapter.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-FFmpegKitConfig.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-FFmpegSession.Plo@am__quote@ # am--include-marker
@@ -667,6 +670,13 @@ libffmpegkit_la-AtomicLong.lo: AtomicLong.m
@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepOBJC_FALSE@ $(AM_V_OBJC@am__nodep@)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_OBJCFLAGS) $(OBJCFLAGS) -c -o libffmpegkit_la-AtomicLong.lo `test -f 'AtomicLong.m' || echo '$(srcdir)/'`AtomicLong.m
+libffmpegkit_la-Chapter.lo: Chapter.m
+@am__fastdepOBJC_TRUE@ $(AM_V_OBJC)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_OBJCFLAGS) $(OBJCFLAGS) -MT libffmpegkit_la-Chapter.lo -MD -MP -MF $(DEPDIR)/libffmpegkit_la-Chapter.Tpo -c -o libffmpegkit_la-Chapter.lo `test -f 'Chapter.m' || echo '$(srcdir)/'`Chapter.m
+@am__fastdepOBJC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libffmpegkit_la-Chapter.Tpo $(DEPDIR)/libffmpegkit_la-Chapter.Plo
+@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ $(AM_V_OBJC)source='Chapter.m' object='libffmpegkit_la-Chapter.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepOBJC_FALSE@ DEPDIR=$(DEPDIR) $(OBJCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepOBJC_FALSE@ $(AM_V_OBJC@am__nodep@)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_OBJCFLAGS) $(OBJCFLAGS) -c -o libffmpegkit_la-Chapter.lo `test -f 'Chapter.m' || echo '$(srcdir)/'`Chapter.m
+
libffmpegkit_la-FFmpegKit.lo: FFmpegKit.m
@am__fastdepOBJC_TRUE@ $(AM_V_OBJC)$(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(OBJC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_OBJCFLAGS) $(OBJCFLAGS) -MT libffmpegkit_la-FFmpegKit.lo -MD -MP -MF $(DEPDIR)/libffmpegkit_la-FFmpegKit.Tpo -c -o libffmpegkit_la-FFmpegKit.lo `test -f 'FFmpegKit.m' || echo '$(srcdir)/'`FFmpegKit.m
@am__fastdepOBJC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libffmpegkit_la-FFmpegKit.Tpo $(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo
@@ -922,6 +932,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libffmpegkit_la-AbstractSession.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-ArchDetect.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-AtomicLong.Plo
+ -rm -f ./$(DEPDIR)/libffmpegkit_la-Chapter.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegKitConfig.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegSession.Plo
@@ -991,6 +1002,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libffmpegkit_la-AbstractSession.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-ArchDetect.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-AtomicLong.Plo
+ -rm -f ./$(DEPDIR)/libffmpegkit_la-Chapter.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegKit.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegKitConfig.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-FFmpegSession.Plo
diff --git a/apple/src/MediaInformation.h b/apple/src/MediaInformation.h
index 20813cf..6d2ea86 100644
--- a/apple/src/MediaInformation.h
+++ b/apple/src/MediaInformation.h
@@ -21,6 +21,7 @@
#define FFMPEG_KIT_MEDIA_INFORMATION_H
#import
+#import "Chapter.h"
#import "StreamInformation.h"
extern NSString* const MediaKeyMediaProperties;
@@ -38,7 +39,7 @@ extern NSString* const MediaKeyTags;
*/
@interface MediaInformation : NSObject
-- (instancetype)init:(NSDictionary*)mediaDictionary withStreams:(NSArray*)streams;
+- (instancetype)init:(NSDictionary*)mediaDictionary withStreams:(NSArray*)streams withChapters:(NSArray*)chapters;
/**
* Returns file name.
@@ -103,6 +104,13 @@ extern NSString* const MediaKeyTags;
*/
- (NSArray*)getStreams;
+/**
+ * Returns all chapters.
+ *
+ * @return chapters array
+ */
+- (NSArray*)getChapters;
+
/**
* Returns the media property associated with the key.
*
diff --git a/apple/src/MediaInformation.m b/apple/src/MediaInformation.m
index c8ba7a9..a9211db 100644
--- a/apple/src/MediaInformation.m
+++ b/apple/src/MediaInformation.m
@@ -41,13 +41,19 @@ NSString* const MediaKeyTags = @"tags";
*/
NSArray *streamArray;
+ /**
+ * Stores chapters.
+ */
+ NSArray *chapterArray;
+
}
-- (instancetype)init:(NSDictionary*)mediaDictionary withStreams:(NSArray*)streams{
+- (instancetype)init:(NSDictionary*)mediaDictionary withStreams:(NSArray*)streams withChapters:(NSArray*)chapters{
self = [super init];
if (self) {
dictionary = mediaDictionary;
streamArray = streams;
+ chapterArray = chapters;
}
return self;
@@ -89,6 +95,10 @@ NSString* const MediaKeyTags = @"tags";
return streamArray;
}
+- (NSArray*)getChapters {
+ return chapterArray;
+}
+
- (NSString*)getStringProperty:(NSString*)key {
NSDictionary* mediaProperties = [self getMediaProperties];
if (mediaProperties == nil) {
diff --git a/apple/src/MediaInformationJsonParser.m b/apple/src/MediaInformationJsonParser.m
index e7fa171..c7fe7cb 100644
--- a/apple/src/MediaInformationJsonParser.m
+++ b/apple/src/MediaInformationJsonParser.m
@@ -19,6 +19,9 @@
#import "MediaInformationJsonParser.h"
+NSString* const MediaInformationJsonParserKeyStreams = @"streams";
+NSString* const MediaInformationJsonParserKeyChapters = @"chapters";
+
@implementation MediaInformationJsonParser
+ (MediaInformation*)from:(NSString*)ffprobeJsonOutput {
@@ -40,14 +43,21 @@
return nil;
}
- NSArray* array = [jsonDictionary objectForKey:@"streams"];
+ NSArray* jsonStreamArray = [jsonDictionary objectForKey:MediaInformationJsonParserKeyStreams];
NSMutableArray *streamArray = [[NSMutableArray alloc] init];
- for(int i = 0; i