Skip to content

Commit

Permalink
feat: Support MP.jpg format
Browse files Browse the repository at this point in the history
  • Loading branch information
CaiJingLong committed Oct 11, 2023
1 parent 083d742 commit a6de7d0
Show file tree
Hide file tree
Showing 10 changed files with 355 additions and 19 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.1.0

- Feat: Support MP.jpg format.

## 1.0.0

- Initial version.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ It like livephoto in iphone.

The file is composed of two files, jpg and mp4.

Usually, the jpg name is MVIMG_XXXXX.jpg.
Usually, the jpg name is `MVIMG_XXXXX.jpg`.
Or, the name is `xxxx.MP.jpg`.

For information about their differences, please refer [here][issue], or view the [xap file in assets][xap].

## Usage

Expand Down Expand Up @@ -59,3 +62,6 @@ void main() {
## License

Apache License 2.0

[issue]: https://github.com/SimpleMobileTools/Simple-Gallery/issues/1426#issuecomment-982855006
[xap]: https://github.com/CaiJingLong/mvimg/tree/main/assets
162 changes: 162 additions & 0 deletions assets/mp.jpg.exif
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Ouput by 'exiftool -a test.MP.jpg > mp.jpg.exif'
# The file have 2708598 bytes video

ExifTool Version Number : 12.60
File Name : test.MP.jpg
Directory : .
File Size : 4.6 MB
File Modification Date/Time : 2023:10:11 08:42:39+08:00
File Access Date/Time : 2023:10:11 08:42:50+08:00
File Inode Change Date/Time : 2023:10:11 08:42:49+08:00
File Permissions : -rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
Exif Byte Order : Little-endian (Intel, II)
Image Width : 3840
Image Height : 2160
Make : Google
Camera Model Name : Pixel 3a
Orientation : Rotate 270 CW
X Resolution : 72
Y Resolution : 72
Resolution Unit : inches
Software : HDR+ 1.0.450594208zd
Modify Date : 2023:04:25 22:55:49
Y Cb Cr Positioning : Centered
Exposure Time : 1/30
F Number : 1.8
Exposure Program : Program AE
ISO : 506
Exif Version : 0232
Date/Time Original : 2023:04:25 22:55:49
Create Date : 2023:04:25 22:55:49
Offset Time : -07:00
Offset Time Original : -07:00
Offset Time Digitized : -07:00
Components Configuration : Y, Cb, Cr, -
Shutter Speed Value : 1/30
Aperture Value : 1.8
Brightness Value : -0.74
Exposure Compensation : 0
Max Aperture Value : 1.8
Subject Distance : 0.114 m
Metering Mode : Center-weighted average
Flash : Off, Did not fire
Focal Length : 4.4 mm
Sub Sec Time : 256
Sub Sec Time Original : 256
Sub Sec Time Digitized : 256
Flashpix Version : 0100
Color Space : sRGB
Exif Image Width : 3840
Exif Image Height : 2160
Interoperability Index : R98 - DCF basic file (sRGB)
Interoperability Version : 0100
Sensing Method : One-chip color area
Scene Type : Directly photographed
Custom Rendered : Custom
Exposure Mode : Auto
White Balance : Auto
Digital Zoom Ratio : 0
Focal Length In 35mm Format : 27 mm
Scene Capture Type : Standard
Contrast : Normal
Saturation : Normal
Sharpness : Normal
Subject Distance Range : Macro
Lens Make : Google
Lens Model : Pixel 3a back camera 4.44mm f/1.8
Composite Image : Composite Image Captured While Shooting
GPS Latitude Ref : North
GPS Latitude : 47 deg 37' 29.36"
GPS Longitude Ref : West
GPS Longitude : 122 deg 18' 24.90"
GPS Altitude Ref : Above Sea Level
GPS Altitude : 94.8 m
GPS Time Stamp : 05:55:45
GPS Img Direction Ref : Magnetic North
GPS Img Direction : 0
GPS Date Stamp : 2023:04:26
Image Width : 480
Image Height : 270
Compression : JPEG (old-style)
Orientation : Horizontal (normal)
X Resolution : 72
Y Resolution : 72
Resolution Unit : inches
Thumbnail Offset : 1344
Thumbnail Length : 17259
XMP Toolkit : Adobe XMP Core 5.1.0-jc003
Motion Photo : 1
Motion Photo Version : 1
Motion Photo Presentation Timestamp Us: 1314346
Has Extended XMP : 443592FF0E9C46CB8B0712C4D88960E9
Directory Item Mime : image/jpeg
Directory Item Semantic : Primary
Directory Item Length : 0
Directory Item Padding : 0
Directory Item Mime : video/mp4
Directory Item Semantic : MotionPhoto
Directory Item Length : 2708598
Directory Item Padding : 0
JFIF Version : 1.02
Resolution Unit : None
X Resolution : 1
Y Resolution : 1
Profile CMM Type :
Profile Version : 4.0.0
Profile Class : Display Device Profile
Color Space Data : RGB
Profile Connection Space : XYZ
Profile Date Time : 2016:12:08 09:38:28
Profile File Signature : acsp
Primary Platform : Unknown ()
CMM Flags : Not Embedded, Independent
Device Manufacturer : Google
Device Model :
Device Attributes : Reflective, Glossy, Positive, Color
Rendering Intent : Perceptual
Connection Space Illuminant : 0.9642 1 0.82491
Profile Creator : Google
Profile ID : 75e1a6b13c34376310c8ab660632a28a
Profile Description : sRGB IEC61966-2.1
Profile Copyright : Copyright (c) 2016 Google Inc.
Media White Point : 0.95045 1 1.08905
Media Black Point : 0 0 0
Red Matrix Column : 0.43604 0.22249 0.01392
Green Matrix Column : 0.38512 0.7169 0.09706
Blue Matrix Column : 0.14305 0.06061 0.71391
Red Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Chromatic Adaptation : 1.04788 0.02292 -0.05019 0.02959 0.99048 -0.01704 -0.00922 0.01508 0.75168
Blue Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Green Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Image Width : 3840
Image Height : 2160
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
HDRP Maker Note : (Binary data 18868 bytes, use -b option to extract)
Shot Log Data : (Binary data 293 bytes, use -b option to extract)
Aperture : 1.8
Image Size : 3840x2160
Megapixels : 8.3
Scale Factor To 35 mm Equivalent: 6.1
Shutter Speed : 1/30
Create Date : 2023:04:25 22:55:49.256-07:00
Date/Time Original : 2023:04:25 22:55:49.256-07:00
Modify Date : 2023:04:25 22:55:49.256-07:00
Thumbnail Image : (Binary data 17259 bytes, use -b option to extract)
GPS Altitude : 94.8 m Above Sea Level
GPS Date/Time : 2023:04:26 05:55:45Z
GPS Latitude : 47 deg 37' 29.36" N
GPS Longitude : 122 deg 18' 24.90" W
Circle Of Confusion : 0.005 mm
Depth Of Field : 0.011 m (0.109 - 0.120 m)
Field Of View : 67.4 deg
Focal Length : 4.4 mm (35 mm equivalent: 27.0 mm)
GPS Position : 47 deg 37' 29.36" N, 122 deg 18' 24.90" W
Hyperfocal Distance : 2.22 m
Light Value : 4.3
Lens ID : Pixel 3a back camera 4.44mm f/1.8
32 changes: 32 additions & 0 deletions assets/mp.xap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.1.0-jc003">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:GCamera="http://ns.google.com/photos/1.0/camera/"
xmlns:Container="http://ns.google.com/photos/1.0/container/"
xmlns:Item="http://ns.google.com/photos/1.0/container/item/"
xmlns:xmpNote="http://ns.adobe.com/xmp/note/"
GCamera:MotionPhoto="1"
GCamera:MotionPhotoVersion="1"
GCamera:MotionPhotoPresentationTimestampUs="1314346"
xmpNote:HasExtendedXMP="443592FF0E9C46CB8B0712C4D88960E9">
<Container:Directory>
<rdf:Seq>
<rdf:li rdf:parseType="Resource">
<Container:Item
Item:Mime="image/jpeg"
Item:Semantic="Primary"
Item:Length="0"
Item:Padding="0"/>
</rdf:li>
<rdf:li rdf:parseType="Resource">
<Container:Item
Item:Mime="video/mp4"
Item:Semantic="MotionPhoto"
Item:Length="2708598"
Item:Padding="0"/>
</rdf:li>
</rdf:Seq>
</Container:Directory>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
86 changes: 86 additions & 0 deletions assets/mvimg.jpg.exif
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
ExifTool Version Number : 12.60
File Name : test.jpg
Directory : .
File Size : 8.8 MB
File Modification Date/Time : 2023:10:10 16:10:50+08:00
File Access Date/Time : 2023:10:10 16:28:38+08:00
File Inode Change Date/Time : 2023:10:10 16:11:01+08:00
File Permissions : -rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
Exif Byte Order : Big-endian (Motorola, MM)
Image Width : 3000
Image Height : 4000
Resolution Unit : inches
Make : Xiaomi
Camera Model Name : M2012K11C
Modify Date : 2023:08:21 12:04:42
Orientation : Horizontal (normal)
Y Cb Cr Positioning : Centered
ISO : 222
Exposure Program : Not Defined
F Number : 1.8
Exposure Time : 1/120
Sensing Method : Unknown (0)
Sub Sec Time Digitized : 015029
Offset Time Original : +08:00
Sub Sec Time Original : 015029
Offset Time : +08:00
Sub Sec Time : 015029
Focal Length : 6.0 mm
Flash : Off, Did not fire
Light Source : D65
Metering Mode : Center-weighted average
Scene Capture Type : Standard
Interoperability Index : R98 - DCF basic file (sRGB)
Interoperability Version : 0100
Focal Length In 35mm Format : 0 mm
Max Aperture Value : 1.7
Create Date : 2023:08:21 12:04:42
Exposure Compensation : 0
Exif Image Height : 4000
White Balance : Auto
Date/Time Original : 2023:08:21 12:04:42
Brightness Value : 0
Exif Image Width : 3000
Exposure Mode : Auto
Aperture Value : 1.7
Components Configuration : Y, Cb, Cr, -
Color Space : sRGB
Scene Type : Unknown (0)
Shutter Speed Value : 1/120
Exif Version : 0220
Flashpix Version : 0100
X Resolution : 72
Y Resolution : 72
Thumbnail Offset : 2029
Thumbnail Length : 22230
Compression : JPEG (old-style)
Resolution Unit : inches
X Resolution : 72
Y Resolution : 72
Exif Image Height : 320
Exif Image Width : 240
XMP Toolkit : Adobe XMP Core 5.1.0-jc003
Micro Video Version : 1
Micro Video : 1
Micro Video Offset : 3507133
Micro Video Presentation Timestamp Us: 905581
XMP Meta : <?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
Image Width : 3000
Image Height : 4000
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
Aperture : 1.8
Image Size : 3000x4000
Megapixels : 12.0
Shutter Speed : 1/120
Create Date : 2023:08:21 12:04:42.015029
Date/Time Original : 2023:08:21 12:04:42.015029+08:00
Modify Date : 2023:08:21 12:04:42.015029+08:00
Thumbnail Image : (Binary data 22230 bytes, use -b option to extract)
Focal Length : 6.0 mm
Light Value : 7.4
12 changes: 12 additions & 0 deletions assets/mvimg.xap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.1.0-jc003">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:GCamera="http://ns.google.com/photos/1.0/camera/"
xmlns:MiCamera="http://ns.xiaomi.com/photos/1.0/camera/"
GCamera:MicroVideoVersion="1"
GCamera:MicroVideo="1"
GCamera:MicroVideoOffset="3507133"
GCamera:MicroVideoPresentationTimestampUs="905581"
MiCamera:XMPMeta="&lt;?xml version='1.0' encoding='UTF-8' standalone='yes' ?&gt;"/>
</rdf:RDF>
</x:xmpmeta>
Binary file added assets/test.MP.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 33 additions & 7 deletions lib/src/mvimg_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,49 @@ class Mvimg {
}

void _readVideoRange(List<int> xapContent) {
final fileLength = input.length;

final text = ascii.decode(xapContent);
final document = XmlDocument.parse(text);
final root = document.rootElement;

final infoElement = root.firstElementChild?.firstElementChild;

final videoOffset = infoElement?.getAttribute('GCamera:MicroVideoOffset');

if (videoOffset == null) {
throw Exception('Can not find video offset');
if (videoOffset != null) {
final videoOffsetInt = int.parse(videoOffset);

_videoRange = _Range(fileLength - videoOffsetInt, fileLength);
return;
}

final videoOffsetInt = int.parse(videoOffset);
final isMotionPhoto =
infoElement?.getAttribute('GCamera:MotionPhoto') == '1';

final fileLength = input.length;
if (isMotionPhoto) {
final children =
infoElement?.firstElementChild?.firstElementChild?.childElements;

if (children != null) {
for (final item in children) {
final container = item.firstElementChild;
final mimeType = container?.getAttribute('Item:Mime');

if (mimeType == 'video/mp4') {
final length = container?.getAttribute('Item:Length');

if (length == null) {
throw Exception('Can not find video length');
}

final videoOffsetInt = int.parse(length);
_videoRange = _Range(fileLength - videoOffsetInt, fileLength);
return;
}
}
}
}

_videoRange = _Range(fileLength - videoOffsetInt, fileLength);
throw Exception('Can not find video range');
}

void dispose() {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: mvimg
description: A library to split mvimg(android motion video) file.
version: 1.0.0
version: 1.1.0
repository: https://github.com/caijinglong/mvimg

environment:
Expand Down
Loading

0 comments on commit a6de7d0

Please sign in to comment.