mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add support for reading location data in MP4 extractor
The geodata is stored in the "udta" box as per MediaMuxer reference https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/libstagefright/MPEG4Writer.cpp;drc=master;l=5588 PiperOrigin-RevId: 515095127
This commit is contained in:
parent
c0a8b944a6
commit
2f01f9c53b
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package androidx.media3.extractor.metadata.mp4;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.media3.common.Metadata;
|
||||||
|
import androidx.media3.common.util.UnstableApi;
|
||||||
|
import com.google.common.primitives.Floats;
|
||||||
|
|
||||||
|
/** Stores MP4 location data. */
|
||||||
|
@UnstableApi
|
||||||
|
public final class Mp4LocationData implements Metadata.Entry {
|
||||||
|
public final float latitude;
|
||||||
|
public final float longitude;
|
||||||
|
|
||||||
|
/** Creates an instance. */
|
||||||
|
public Mp4LocationData(float latitude, float longitude) {
|
||||||
|
this.latitude = latitude;
|
||||||
|
this.longitude = longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mp4LocationData(Parcel in) {
|
||||||
|
latitude = in.readFloat();
|
||||||
|
longitude = in.readFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null || getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Mp4LocationData other = (Mp4LocationData) obj;
|
||||||
|
return latitude == other.latitude && longitude == other.longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 17;
|
||||||
|
result = 31 * result + Floats.hashCode(latitude);
|
||||||
|
result = 31 * result + Floats.hashCode(longitude);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "xyz: latitude=" + latitude + " longitude=" + longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parcelable implementation.
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeFloat(latitude);
|
||||||
|
dest.writeFloat(longitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Parcelable.Creator<Mp4LocationData> CREATOR =
|
||||||
|
new Parcelable.Creator<Mp4LocationData>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mp4LocationData createFromParcel(Parcel in) {
|
||||||
|
return new Mp4LocationData(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mp4LocationData[] newArray(int size) {
|
||||||
|
return new Mp4LocationData[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -347,6 +347,9 @@ import java.util.List;
|
|||||||
@SuppressWarnings("ConstantCaseForConstants")
|
@SuppressWarnings("ConstantCaseForConstants")
|
||||||
public static final int TYPE_meta = 0x6d657461;
|
public static final int TYPE_meta = 0x6d657461;
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantCaseForConstants")
|
||||||
|
public static final int TYPE_xyz = 0xa978797a;
|
||||||
|
|
||||||
@SuppressWarnings("ConstantCaseForConstants")
|
@SuppressWarnings("ConstantCaseForConstants")
|
||||||
public static final int TYPE_smta = 0x736d7461;
|
public static final int TYPE_smta = 0x736d7461;
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ import androidx.media3.extractor.ExtractorUtil;
|
|||||||
import androidx.media3.extractor.GaplessInfoHolder;
|
import androidx.media3.extractor.GaplessInfoHolder;
|
||||||
import androidx.media3.extractor.HevcConfig;
|
import androidx.media3.extractor.HevcConfig;
|
||||||
import androidx.media3.extractor.OpusUtil;
|
import androidx.media3.extractor.OpusUtil;
|
||||||
|
import androidx.media3.extractor.metadata.mp4.Mp4LocationData;
|
||||||
import androidx.media3.extractor.metadata.mp4.SmtaMetadataEntry;
|
import androidx.media3.extractor.metadata.mp4.SmtaMetadataEntry;
|
||||||
import androidx.media3.extractor.mp4.Atom.LeafAtom;
|
import androidx.media3.extractor.mp4.Atom.LeafAtom;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
@ -58,6 +59,26 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
@SuppressWarnings("ConstantField")
|
@SuppressWarnings("ConstantField")
|
||||||
/* package */ final class AtomParsers {
|
/* package */ final class AtomParsers {
|
||||||
|
|
||||||
|
/** Stores metadata retrieved from the udta atom. */
|
||||||
|
public static final class UdtaInfo {
|
||||||
|
/** The metadata retrieved from the meta sub atom. */
|
||||||
|
@Nullable public final Metadata metaMetadata;
|
||||||
|
/** The metadata retrieved from the smta sub atom. */
|
||||||
|
@Nullable public final Metadata smtaMetadata;
|
||||||
|
/** The location metadata retrieved from the xyz sub atom. */
|
||||||
|
@Nullable public final Metadata xyzMetadata;
|
||||||
|
|
||||||
|
/** Creates an instance. */
|
||||||
|
public UdtaInfo(
|
||||||
|
@Nullable Metadata metaMetadata,
|
||||||
|
@Nullable Metadata smtaMetadata,
|
||||||
|
@Nullable Metadata xyzMetadata) {
|
||||||
|
this.metaMetadata = metaMetadata;
|
||||||
|
this.smtaMetadata = smtaMetadata;
|
||||||
|
this.xyzMetadata = xyzMetadata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final String TAG = "AtomParsers";
|
private static final String TAG = "AtomParsers";
|
||||||
|
|
||||||
@SuppressWarnings("ConstantCaseForConstants")
|
@SuppressWarnings("ConstantCaseForConstants")
|
||||||
@ -157,15 +178,15 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
* Parses a udta atom.
|
* Parses a udta atom.
|
||||||
*
|
*
|
||||||
* @param udtaAtom The udta (user data) atom to decode.
|
* @param udtaAtom The udta (user data) atom to decode.
|
||||||
* @return A {@link Pair} containing the metadata from the meta child atom as first value (if
|
* @return A {@link UdtaInfo} containing the metadata extracted from the meta, smta and xyz child
|
||||||
* any), and the metadata from the smta child atom as second value (if any).
|
* atoms (if present).
|
||||||
*/
|
*/
|
||||||
public static Pair<@NullableType Metadata, @NullableType Metadata> parseUdta(
|
public static UdtaInfo parseUdta(Atom.LeafAtom udtaAtom) {
|
||||||
Atom.LeafAtom udtaAtom) {
|
|
||||||
ParsableByteArray udtaData = udtaAtom.data;
|
ParsableByteArray udtaData = udtaAtom.data;
|
||||||
udtaData.setPosition(Atom.HEADER_SIZE);
|
udtaData.setPosition(Atom.HEADER_SIZE);
|
||||||
@Nullable Metadata metaMetadata = null;
|
@Nullable Metadata metaMetadata = null;
|
||||||
@Nullable Metadata smtaMetadata = null;
|
@Nullable Metadata smtaMetadata = null;
|
||||||
|
@Nullable Metadata xyzMetadata = null;
|
||||||
while (udtaData.bytesLeft() >= Atom.HEADER_SIZE) {
|
while (udtaData.bytesLeft() >= Atom.HEADER_SIZE) {
|
||||||
int atomPosition = udtaData.getPosition();
|
int atomPosition = udtaData.getPosition();
|
||||||
int atomSize = udtaData.readInt();
|
int atomSize = udtaData.readInt();
|
||||||
@ -176,10 +197,12 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
} else if (atomType == Atom.TYPE_smta) {
|
} else if (atomType == Atom.TYPE_smta) {
|
||||||
udtaData.setPosition(atomPosition);
|
udtaData.setPosition(atomPosition);
|
||||||
smtaMetadata = parseSmta(udtaData, atomPosition + atomSize);
|
smtaMetadata = parseSmta(udtaData, atomPosition + atomSize);
|
||||||
|
} else if (atomType == Atom.TYPE_xyz) {
|
||||||
|
xyzMetadata = parseXyz(udtaData);
|
||||||
}
|
}
|
||||||
udtaData.setPosition(atomPosition + atomSize);
|
udtaData.setPosition(atomPosition + atomSize);
|
||||||
}
|
}
|
||||||
return Pair.create(metaMetadata, smtaMetadata);
|
return new UdtaInfo(metaMetadata, smtaMetadata, xyzMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -760,6 +783,27 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
return entries.isEmpty() ? null : new Metadata(entries);
|
return entries.isEmpty() ? null : new Metadata(entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Parses the location metadata from the xyz atom. */
|
||||||
|
@Nullable
|
||||||
|
private static Metadata parseXyz(ParsableByteArray xyzBox) {
|
||||||
|
int length = xyzBox.readShort();
|
||||||
|
xyzBox.skipBytes(2); // language code.
|
||||||
|
String location = xyzBox.readString(length);
|
||||||
|
// The location string looks like "+35.1345-15.1020/".
|
||||||
|
int plusSignIndex = location.lastIndexOf('+');
|
||||||
|
int minusSignIndex = location.lastIndexOf('-');
|
||||||
|
int latitudeEndIndex = max(plusSignIndex, minusSignIndex);
|
||||||
|
try {
|
||||||
|
float latitude = Float.parseFloat(location.substring(0, latitudeEndIndex));
|
||||||
|
float longitude =
|
||||||
|
Float.parseFloat(location.substring(latitudeEndIndex, location.length() - 1));
|
||||||
|
return new Metadata(new Mp4LocationData(latitude, longitude));
|
||||||
|
} catch (IndexOutOfBoundsException | NumberFormatException exception) {
|
||||||
|
// Invalid input.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses metadata from a Samsung smta atom.
|
* Parses metadata from a Samsung smta atom.
|
||||||
*
|
*
|
||||||
|
@ -23,7 +23,6 @@ import static java.lang.Math.max;
|
|||||||
import static java.lang.Math.min;
|
import static java.lang.Math.min;
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
import android.util.Pair;
|
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
@ -58,7 +57,6 @@ import java.lang.annotation.Target;
|
|||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
/** Extracts data from the MP4 container format. */
|
/** Extracts data from the MP4 container format. */
|
||||||
@ -494,14 +492,15 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
|||||||
// Process metadata.
|
// Process metadata.
|
||||||
@Nullable Metadata udtaMetaMetadata = null;
|
@Nullable Metadata udtaMetaMetadata = null;
|
||||||
@Nullable Metadata smtaMetadata = null;
|
@Nullable Metadata smtaMetadata = null;
|
||||||
|
@Nullable Metadata xyzMetadata = null;
|
||||||
boolean isQuickTime = fileType == FILE_TYPE_QUICKTIME;
|
boolean isQuickTime = fileType == FILE_TYPE_QUICKTIME;
|
||||||
GaplessInfoHolder gaplessInfoHolder = new GaplessInfoHolder();
|
GaplessInfoHolder gaplessInfoHolder = new GaplessInfoHolder();
|
||||||
@Nullable Atom.LeafAtom udta = moov.getLeafAtomOfType(Atom.TYPE_udta);
|
@Nullable Atom.LeafAtom udta = moov.getLeafAtomOfType(Atom.TYPE_udta);
|
||||||
if (udta != null) {
|
if (udta != null) {
|
||||||
Pair<@NullableType Metadata, @NullableType Metadata> udtaMetadata =
|
AtomParsers.UdtaInfo udtaInfo = AtomParsers.parseUdta(udta);
|
||||||
AtomParsers.parseUdta(udta);
|
udtaMetaMetadata = udtaInfo.metaMetadata;
|
||||||
udtaMetaMetadata = udtaMetadata.first;
|
smtaMetadata = udtaInfo.smtaMetadata;
|
||||||
smtaMetadata = udtaMetadata.second;
|
xyzMetadata = udtaInfo.xyzMetadata;
|
||||||
if (udtaMetaMetadata != null) {
|
if (udtaMetaMetadata != null) {
|
||||||
gaplessInfoHolder.setFromMetadata(udtaMetaMetadata);
|
gaplessInfoHolder.setFromMetadata(udtaMetaMetadata);
|
||||||
}
|
}
|
||||||
@ -562,7 +561,8 @@ public final class Mp4Extractor implements Extractor, SeekMap {
|
|||||||
mdtaMetadata,
|
mdtaMetadata,
|
||||||
formatBuilder,
|
formatBuilder,
|
||||||
smtaMetadata,
|
smtaMetadata,
|
||||||
slowMotionMetadataEntries.isEmpty() ? null : new Metadata(slowMotionMetadataEntries));
|
slowMotionMetadataEntries.isEmpty() ? null : new Metadata(slowMotionMetadataEntries),
|
||||||
|
xyzMetadata);
|
||||||
mp4Track.trackOutput.format(formatBuilder.build());
|
mp4Track.trackOutput.format(formatBuilder.build());
|
||||||
|
|
||||||
if (track.type == C.TRACK_TYPE_VIDEO && firstVideoTrackIndex == C.INDEX_UNSET) {
|
if (track.type == C.TRACK_TYPE_VIDEO && firstVideoTrackIndex == C.INDEX_UNSET) {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
seekMap:
|
seekMap:
|
||||||
isSeekable = true
|
isSeekable = true
|
||||||
duration = 1024000
|
duration = 1024000
|
||||||
getPosition(0) = [[timeUs=0, position=48]]
|
getPosition(0) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1) = [[timeUs=0, position=48]]
|
getPosition(1) = [[timeUs=0, position=2269]]
|
||||||
getPosition(512000) = [[timeUs=0, position=48]]
|
getPosition(512000) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1024000) = [[timeUs=0, position=48]]
|
getPosition(1024000) = [[timeUs=0, position=2269]]
|
||||||
numberOfTracks = 2
|
numberOfTracks = 2
|
||||||
track 0:
|
track 0:
|
||||||
total output bytes = 89876
|
total output bytes = 89876
|
||||||
@ -17,6 +17,7 @@ track 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
@ -152,7 +153,7 @@ track 1:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
language = und
|
language = und
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 2, hash 5F7
|
data = length 2, hash 5F7
|
||||||
sample 0:
|
sample 0:
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
seekMap:
|
seekMap:
|
||||||
isSeekable = true
|
isSeekable = true
|
||||||
duration = 1024000
|
duration = 1024000
|
||||||
getPosition(0) = [[timeUs=0, position=48]]
|
getPosition(0) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1) = [[timeUs=0, position=48]]
|
getPosition(1) = [[timeUs=0, position=2269]]
|
||||||
getPosition(512000) = [[timeUs=0, position=48]]
|
getPosition(512000) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1024000) = [[timeUs=0, position=48]]
|
getPosition(1024000) = [[timeUs=0, position=2269]]
|
||||||
numberOfTracks = 2
|
numberOfTracks = 2
|
||||||
track 0:
|
track 0:
|
||||||
total output bytes = 89876
|
total output bytes = 89876
|
||||||
@ -17,6 +17,7 @@ track 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
@ -152,7 +153,7 @@ track 1:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
language = und
|
language = und
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 2, hash 5F7
|
data = length 2, hash 5F7
|
||||||
sample 0:
|
sample 0:
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
seekMap:
|
seekMap:
|
||||||
isSeekable = true
|
isSeekable = true
|
||||||
duration = 1024000
|
duration = 1024000
|
||||||
getPosition(0) = [[timeUs=0, position=48]]
|
getPosition(0) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1) = [[timeUs=0, position=48]]
|
getPosition(1) = [[timeUs=0, position=2269]]
|
||||||
getPosition(512000) = [[timeUs=0, position=48]]
|
getPosition(512000) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1024000) = [[timeUs=0, position=48]]
|
getPosition(1024000) = [[timeUs=0, position=2269]]
|
||||||
numberOfTracks = 2
|
numberOfTracks = 2
|
||||||
track 0:
|
track 0:
|
||||||
total output bytes = 89876
|
total output bytes = 89876
|
||||||
@ -17,6 +17,7 @@ track 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
@ -152,7 +153,7 @@ track 1:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
language = und
|
language = und
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 2, hash 5F7
|
data = length 2, hash 5F7
|
||||||
sample 0:
|
sample 0:
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
seekMap:
|
seekMap:
|
||||||
isSeekable = true
|
isSeekable = true
|
||||||
duration = 1024000
|
duration = 1024000
|
||||||
getPosition(0) = [[timeUs=0, position=48]]
|
getPosition(0) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1) = [[timeUs=0, position=48]]
|
getPosition(1) = [[timeUs=0, position=2269]]
|
||||||
getPosition(512000) = [[timeUs=0, position=48]]
|
getPosition(512000) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1024000) = [[timeUs=0, position=48]]
|
getPosition(1024000) = [[timeUs=0, position=2269]]
|
||||||
numberOfTracks = 2
|
numberOfTracks = 2
|
||||||
track 0:
|
track 0:
|
||||||
total output bytes = 89876
|
total output bytes = 89876
|
||||||
@ -17,6 +17,7 @@ track 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
@ -152,7 +153,7 @@ track 1:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
language = und
|
language = und
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 2, hash 5F7
|
data = length 2, hash 5F7
|
||||||
sample 0:
|
sample 0:
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
seekMap:
|
seekMap:
|
||||||
isSeekable = true
|
isSeekable = true
|
||||||
duration = 1024000
|
duration = 1024000
|
||||||
getPosition(0) = [[timeUs=0, position=48]]
|
getPosition(0) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1) = [[timeUs=0, position=48]]
|
getPosition(1) = [[timeUs=0, position=2269]]
|
||||||
getPosition(512000) = [[timeUs=0, position=48]]
|
getPosition(512000) = [[timeUs=0, position=2269]]
|
||||||
getPosition(1024000) = [[timeUs=0, position=48]]
|
getPosition(1024000) = [[timeUs=0, position=2269]]
|
||||||
numberOfTracks = 2
|
numberOfTracks = 2
|
||||||
track 0:
|
track 0:
|
||||||
total output bytes = 89876
|
total output bytes = 89876
|
||||||
@ -17,6 +17,7 @@ track 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
@ -152,7 +153,7 @@ track 1:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
language = und
|
language = und
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 2, hash 5F7
|
data = length 2, hash 5F7
|
||||||
sample 0:
|
sample 0:
|
||||||
|
Binary file not shown.
@ -6,6 +6,7 @@ format 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
@ -14,7 +15,7 @@ format 1:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 48000
|
sampleRate = 48000
|
||||||
pcmEncoding = 2
|
pcmEncoding = 2
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
sample:
|
sample:
|
||||||
trackIndex = 1
|
trackIndex = 1
|
||||||
dataHashCode = 1868041800
|
dataHashCode = 1868041800
|
||||||
|
@ -6,6 +6,7 @@ format 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
@ -18,7 +19,7 @@ format 1:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
language = und
|
language = und
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 2, hash 5F7
|
data = length 2, hash 5F7
|
||||||
sample:
|
sample:
|
||||||
|
@ -3,7 +3,7 @@ format 0:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
pcmEncoding = 2
|
pcmEncoding = 2
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
sample:
|
sample:
|
||||||
trackIndex = 0
|
trackIndex = 0
|
||||||
dataHashCode = 915609509
|
dataHashCode = 915609509
|
||||||
|
@ -6,6 +6,7 @@ format 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
@ -18,7 +19,7 @@ format 1:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
language = und
|
language = und
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 2, hash 5F7
|
data = length 2, hash 5F7
|
||||||
sample:
|
sample:
|
||||||
|
@ -6,6 +6,7 @@ format 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
|
@ -7,7 +7,7 @@ format 0:
|
|||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
language = und
|
language = und
|
||||||
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0]]
|
metadata = entries=[TSSE: description=null: values=[Lavf56.1.0], xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 2, hash 5F7
|
data = length 2, hash 5F7
|
||||||
sample:
|
sample:
|
||||||
|
@ -6,6 +6,7 @@ format 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
|
@ -6,6 +6,7 @@ format 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
|
@ -6,6 +6,7 @@ format 0:
|
|||||||
width = 1080
|
width = 1080
|
||||||
height = 720
|
height = 720
|
||||||
frameRate = 29.970028
|
frameRate = 29.970028
|
||||||
|
metadata = entries=[xyz: latitude=40.68 longitude=-74.5]
|
||||||
initializationData:
|
initializationData:
|
||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
|
Loading…
x
Reference in New Issue
Block a user