Skip to content

Commit

Permalink
feat: add video size and duration (#108)
Browse files Browse the repository at this point in the history
* feat: add video size and duration

* handle video metada on android

* add duration to readme
  • Loading branch information
achorein committed Sep 25, 2024
1 parent 186f4cd commit c561966
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 19 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,13 @@ export default const App = () => {
const { shareIntent } = useShareIntent();
```

| attribute | description | example |
| ------------------------ | ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `shareIntent.text` | raw text from text/weburl (ios) and text/\* (android) | "`some text`", "`http://example.com`", "`Hey, Click on my link : http://example.com/nickname`" |
| `shareIntent.webUrl` | link extracted from raw text | `null`, "`http://example.com`", "`http://example.com/nickname`" |
| `shareIntent.files` | image / movies / audio / files with name, path, mimetype, size (in octets) and image dimension (width/height) | `[{ path: "file:///local/path/filename", mimeType: "image/jpeg", fileName: "originalFilename.jpg", size: 2567402, width: 800, height: 600 }]` |
| `shareIntent.meta` | meta object which contains extra information about the share intent | `{ title: "My cool blog article" }` |
| `shareIntent.meta.title` | optional title property sent by other app. Currently only filled on Android | `My cool blog article` |
| attribute | description | example |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `shareIntent.text` | raw text from text/weburl (ios) and text/\* (android) | "`some text`", "`http://example.com`", "`Hey, Click on my link : http://example.com/nickname`" |
| `shareIntent.webUrl` | link extracted from raw text | `null`, "`http://example.com`", "`http://example.com/nickname`" |
| `shareIntent.files` | image / movies / audio / files with name, path, mimetype, size (in octets) and image/video dimensions (width/height/duration) | `[{ path: "file:///local/path/filename", mimeType: "image/jpeg", fileName: "originalFilename.jpg", size: 2567402, width: 800, height: 600 }, { path: "file:///local/path/filename", mimeType: "video/mp4", fileName: "originalFilename.mp4", size: 2567402, width: 800, height: 600, duration: 20000 }]` |
| `shareIntent.meta` | meta object which contains extra information about the share intent | `{ title: "My cool blog article" }` |
| `shareIntent.meta.title` | optional title property sent by other app. Currently only filled on Android | `My cool blog article` |

#### Customize Content Types in `app.json`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever;
import android.net.Uri
import android.os.Build
import android.os.Environment
Expand Down Expand Up @@ -65,15 +66,23 @@ class ExpoShareIntentModule : Module() {

val mimeType = resolver.getType(uri)!!

var imageHeight: String? = null;
var imageWidth: String? = null;
var mediaWidth: String? = null;
var mediaHeight: String? = null;
var mediaDuration: String? = null;
if (mimeType.startsWith("image/")) {
val options = BitmapFactory.Options().apply {
inJustDecodeBounds = true
}
BitmapFactory.decodeStream(resolver.openInputStream(uri), null, options)
imageHeight = options.outHeight.toString()
imageWidth = options.outWidth.toString()
mediaHeight = options.outHeight.toString()
mediaWidth = options.outWidth.toString()
}
if (mimeType.startsWith("video/")) {
val retriever = MediaMetadataRetriever()
retriever.setDataSource(instance?.getAbsolutePath(uri))
mediaWidth = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toInt().toString() ?: null
mediaHeight = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toInt().toString() ?: null
mediaDuration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toInt().toString() ?: null
}

return mapOf(
Expand All @@ -82,8 +91,9 @@ class ExpoShareIntentModule : Module() {
"fileName" to fileName,
"fileSize" to fileSize,
"mimeType" to mimeType,
"width" to imageWidth,
"height" to imageHeight
"width" to mediaWidth,
"height" to mediaHeight,
"duration" to mediaDuration
)
}

Expand Down
1 change: 1 addition & 0 deletions example/basic/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ function FileMeta({ file }: { file: ShareIntentFile }) {
{file.width} x {file.height}
</Text>
)}
{file.duration && <Text>{file.duration}ms</Text>}
</View>
);
}
Expand Down
2 changes: 1 addition & 1 deletion example/basic/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"NSExtensionActivationSupportsMovieWithMaxCount": 1,
"NSExtensionActivationSupportsFileWithMaxCount": 1
},
"androidIntentFilters": ["text/*", "image/*"],
"androidIntentFilters": ["text/*", "image/*", "video/*"],
"androidMultiIntentFilters": ["image/*"],
"disableIOS": false,
"disableAndroid": false
Expand Down
20 changes: 15 additions & 5 deletions plugin/src/ios/ShareExtensionViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -373,14 +373,24 @@ class ShareViewController: UIViewController {
-> SharedMediaFile?
{
let asset = AVAsset(url: forVideo)
let duration = (CMTimeGetSeconds(asset.duration) * 1000).rounded()
let thumbnailPath = getThumbnailPath(for: forVideo)
let duration = (CMTimeGetSeconds(asset.duration) * 1000).rounded()
var trackWidth: Int? = nil
var trackHeight: Int? = nil

// get video info
let track = asset.tracks(withMediaType: AVMediaType.video).first ?? nil
if track != nil {
let size = track!.naturalSize.applying(track!.preferredTransform)
trackWidth = abs(Int(size.width))
trackHeight = abs(Int(size.height))
}

if FileManager.default.fileExists(atPath: thumbnailPath.path) {
return SharedMediaFile(
path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, fileName: fileName,
fileSize: fileSize, width: nil, height: nil, duration: duration, mimeType: mimeType,
type: .video)
fileSize: fileSize, width: trackWidth, height: trackHeight, duration: duration,
mimeType: mimeType, type: .video)
}

var saved = false
Expand All @@ -399,8 +409,8 @@ class ShareViewController: UIViewController {
return saved
? SharedMediaFile(
path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, fileName: fileName,
fileSize: fileSize, width: nil, height: nil, duration: duration, mimeType: mimeType,
type: .video) : nil
fileSize: fileSize, width: trackWidth, height: trackHeight, duration: duration,
mimeType: mimeType, type: .video) : nil
}

private func getThumbnailPath(for url: URL) -> URL {
Expand Down
3 changes: 3 additions & 0 deletions src/ExpoShareIntentModule.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export type ShareIntentFile = {
size: number | null;
width: number | null;
height: number | null;
duration: number | null;
};

/**
Expand All @@ -96,6 +97,7 @@ export interface IosShareIntentFile {
type: "0" | "1" | "2" | "3"; // native type ("0": media, "1": text, "2": weburl, "3": file)
width: number | null;
height: number | null;
duration: number | null; // in ms
}

/**
Expand All @@ -109,6 +111,7 @@ export interface AndroidShareIntentFile {
fileSize?: string; // in octet
width: number | null;
height: number | null;
duration: number | null; // in ms
}

export type NativeShareIntent = AndroidShareIntent | IosShareIntent;
Expand Down
1 change: 1 addition & 0 deletions src/useShareIntent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const parseShareIntent = (
width: file.width ? Number(file.width) : null,
height: file.height ? Number(file.height) : null,
size: file.fileSize ? Number(file.fileSize) : null,
duration: file.duration ? Number(file.duration) : null,
},
];
}, [])
Expand Down

0 comments on commit c561966

Please sign in to comment.