Currently I’m using expo 36. I’m struggling to compress video. Image manipulator works for images but not able to compress video. Also I don’t want to eject the project as of now so is there any other way?
Any updates by chance?
Wow, nothing huh? Gotta love a responsive team.
What did you find out? This forum is basically dead
I did a workaround and still hoping to upgrade it because it is extremely clunky and needs some love but it allows users to upload their videos to a pro Vimeo account, where Vimeo takes care of the compression. And oddly enough it works. Also, It looks like I need to try catch this for when things don’t go as planned but hopefully there is something helpful here for someone who needs a fix for this. I still have to believe there is a better solution out there and I will continue searching for it. I am using firebase firestore to hold all the data and eventually, as you can see in the code the uploaded video/image url is sent as part of the post that is generate.
Here is the function I am using to pick the image/video:
const pickImageFunc = async () => {
const loadingImage = require("../../assets/upload-image-loading.png");
const picPath = `/kosmique/posts/${currentUserUID}/${Math.round(
Math.random() * 100000000
)}`;
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: false,
aspect: [4, 4],
quality: 1,
includeBase64: false,
});
let info;
if (!result.canceled) {
const asset = result.assets[0];
let fileFormat, resultUrl;
setBlankImage(loadingImage);
if (asset.uri.includes("quicktime") || asset.uri.includes(".mov")) {
fileFormat = "video/quicktime";
} else if (asset.uri.includes("mp4")) {
fileFormat = "mp4";
}
setErrorMessage("");
if (
asset.uri.includes("data:video") ||
asset.uri.includes(".mov") ||
asset.uri.includes(".mp4")
) {
info = await returnVideoResultUrl(result, picPath, fileFormat);
const theBody = {
upload: {
approach: "pull",
size: info.metadata.size,
link: info.remoteURL,
},
};
fetch("https://api.vimeo.com/me/videos", {
method: "POST",
headers: new Headers({
Authorization: `Bearer ${envVars.VIMEO_TOKEN}`,
"Content-Type": "application/json",
}),
body: JSON.stringify(theBody),
})
.then((response) => response.json())
.then((data) => {
setPostObj({
...postObj,
image:info.remoteURL,
media:data.uri.replace("/videos/", ""),
mediaType: 'video',
})
})
.catch((error) => {
console.error("Error:", error);
});
} else {
resultUrl = await returnImageResultUrl(asset, picPath);
setPostObj({
...postObj,
image:resultUrl.remoteURL,
media:resultUrl.remoteURL,
mediaType: 'image',
})
}
setReadyToSubmit(true);
}
};
Here is the function I use to interface with the Firebase and Vimeo. This step may be able to be condensed into the uploadImage functionality on the next function.
import { uploadImage } from '../API/firebaseMethods';
export default async function returnVideoResultUrl(
result,
picPath,
fileFormat
) {
if (!result.cancelled) {
const resultUrl = await uploadImage(picPath, result.uri, fileFormat);
return resultUrl;
}
}
the naming of this function is slightly misleading, it uploads images and videos to their respective destinations
export const uploadImage = async (picPath, image, format) => {
// Implement a new Blob promise with XMLHTTPRequest
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function () {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", image, true);
xhr.send(null);
});
// Create a ref in Firebase (I'm using my user's ID)
const ref = firebase.storage().ref().child(picPath);
// Upload blob to Firebase
const snapshot = await ref.put(blob, { contentType: format });
// Create a download URL
const remoteURL = await snapshot.ref.getDownloadURL();
const metadata = await snapshot.ref.getMetadata();
// Return the URL
return { remoteURL, metadata };
};
See also: