Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Video] Add dimension info to share intent #5639

Merged
merged 4 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions modules/Share-with-Bluesky/ShareViewController.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import UIKit
import AVKit

let IMAGE_EXTENSIONS: [String] = ["png", "jpg", "jpeg", "gif", "heic"]
let MOVIE_EXTENSIONS: [String] = ["mov", "mp4", "m4v"]
Expand Down Expand Up @@ -119,16 +120,11 @@ class ShareViewController: UIViewController {
private func handleVideos(items: [NSItemProvider]) async {
let firstItem = items.first

if let dataUri = try? await firstItem?.loadItem(forTypeIdentifier: "public.movie") as? URL {
let ext = String(dataUri.lastPathComponent.split(separator: ".").last ?? "mp4")
if let tempUrl = getTempUrl(ext: ext) {
let data = try? Data(contentsOf: dataUri)
try? data?.write(to: tempUrl)

if let encoded = tempUrl.absoluteString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed),
let url = URL(string: "\(self.appScheme)://intent/compose?videoUri=\(encoded)") {
_ = self.openURL(url)
}
if let dataUrl = try? await firstItem?.loadItem(forTypeIdentifier: "public.movie") as? URL {
let ext = String(dataUrl.lastPathComponent.split(separator: ".").last ?? "mp4")
if let videoUriInfo = saveVideoWithInfo(dataUrl),
let url = URL(string: "\(self.appScheme)://intent/compose?videoUri=\(videoUriInfo)") {
_ = self.openURL(url)
}
}

Expand All @@ -152,6 +148,20 @@ class ShareViewController: UIViewController {
} catch {}
return nil
}

private func saveVideoWithInfo(_ dataUrl: URL) -> String? {
let ext = String(dataUrl.lastPathComponent.split(separator: ".").last ?? "mp4")
guard let tempUrl = getTempUrl(ext: ext),
let track = AVURLAsset(url: dataUrl).tracks(withMediaType: AVMediaType.video).first else {
return nil
}
let size = track.naturalSize.applying(track.preferredTransform)

let data = try? Data(contentsOf: dataUrl)
try? data?.write(to: tempUrl)

return "\(tempUrl.absoluteString)|\(size.width)||\(size.height)"
}

private func completeRequest() {
self.extensionContext?.completeRequest(returningItems: nil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package xyz.blueskyweb.app.exporeceiveandroidintents

import android.content.Intent
import android.graphics.Bitmap
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
Expand Down Expand Up @@ -143,7 +144,10 @@ class ExpoReceiveAndroidIntentsModule : Module() {
appContext.currentActivity?.contentResolver?.openInputStream(uri)?.use {
it.copyTo(out)
}
"bluesky://intent/compose?videoUri=${URLEncoder.encode(file.path, "UTF-8")}".toUri().let {

val info = getVideoInfo(uri) ?: return

"bluesky://intent/compose?videoUri=${URLEncoder.encode(file.path, "UTF-8")}|${info["width"]}|${info["height"]}".toUri().let {
val newIntent = Intent(Intent.ACTION_VIEW, it)
appContext.currentActivity?.startActivity(newIntent)
}
Expand All @@ -166,6 +170,24 @@ class ExpoReceiveAndroidIntentsModule : Module() {
)
}

private fun getVideoInfo(uri: Uri): Map<String, Any>? {
val retriever = MediaMetadataRetriever()
retriever.setDataSource(appContext.currentActivity, uri)

val width = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)?.toIntOrNull()
val height = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)?.toIntOrNull()

if (width == null || height == null) {
return null
}

return mapOf(
"width" to width,
"height" to height,
"path" to uri.path.toString(),
)
}

private fun createFile(extension: String): File = File.createTempFile(extension, "temp.$extension", appContext.currentActivity?.cacheDir)

// We will pas the width and height to the app here, since getting measurements
Expand Down
3 changes: 2 additions & 1 deletion src/lib/hooks/useIntentHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,10 @@ export function useComposeIntent() {

// Whenever a video URI is present, we don't support adding images right now.
if (videoUri) {
const [uri, width, height] = videoUri.split('|')
openComposer({
text: text ?? undefined,
videoUri,
videoUri: {uri, width: Number(width), height: Number(height)},
})
return
}
Expand Down
2 changes: 1 addition & 1 deletion src/state/shell/composer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface ComposerOpts {
openEmojiPicker?: (pos: DOMRect | undefined) => void
text?: string
imageUris?: {uri: string; width: number; height: number; altText?: string}[]
videoUri?: string
videoUri?: {uri: string; width: number; height: number}
}

type StateContext = ComposerOpts | undefined
Expand Down
2 changes: 1 addition & 1 deletion src/view/com/composer/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export const ComposePost = ({
// Whenever we receive an initial video uri, we should immediately run compression if necessary
useEffect(() => {
if (initVideoUri) {
selectVideo({uri: initVideoUri} as ImagePickerAsset)
selectVideo(initVideoUri)
}
}, [initVideoUri, selectVideo])

Expand Down
Loading