After a successful file import, you’ll see the status of the three tabs change. If you encounter playback failure with newer video encoding formats like H265, don’t panic. This won’t affect subsequent transcoding operations. The successfully transcoded CONVERTED video will automatically replace the unplayable RAW video. In other cases, the 🎥 tab only displays the RAW video. After transcoding, the 🖼️ tab will show a compare slider, similar to Squoosh’s slider, to easily compare the image quality difference before and after compression. The live photo control refreshes every time you switch to it and prioritizes loading CONVERTED files.
To provide the most authentic experience, I used Apple’s official LivePhotosKit JS for displaying live photos. You can achieve a similar effect with CSS, and it has many advantages. The principle is not complicated: the core idea is to fade out the original image while zooming in and fading in the video.
-qscale:v
to control image compression quality, just check the ✔️Manual Parameters box. ⚠️Friendly reminder: do not modify the input and output filenames in the parameters. Clicking the download button will expand a dropdown menu; click the title again to start the download. The button next to it allows you to change the filename (without the extension), and this name will be used for both downloading and uploading.The 2x2 labels above the buttons show the file size and (expected) resolution for 🖼️ and 🎥. The left side of the arrow is RAW, and the right side is CONVERTED. After the conversion is complete, the → on the right will turn a prominent green.
The three buttons to the right of the multi-thread switch correspond to Resize, 🎬Video Transcoding Settings, and 🖼️Image Transcoding Settings.
I was once misled by this article, thinking that LivePhotosKit had strict requirements for resolution and format. In reality, it doesn’t restrict resolution, nor does it mandate JPG format, but it really can’t play H265 encoded videos, even if the browser itself supports it. Nevertheless, I still set a friendly default maximum size for web display: 🖼️1008 x 1344 and 🎥720 x 960 (maintaining the aspect ratio). You can reset this at any time with the ⟳ button in the top right corner of the pop-up, or click ⛶ to keep the original size.
🎬 Video settings include whether to keep audio, set the transcoding format (mp4, mov, and webm), and precise trimming. Drag the 🎥 progress bar to your desired position and click 📸 to record the start and end timestamps. If the RAW video cannot be played, you can manually enter the time or transcode it first and then trim it. Additionally, the transcoding format selected here will also affect the extension of the file returned after cloud transcoding (unless you’ve hardcoded it in the API URL).
🖼️ Image settings include transcoding formats (jpg, png, and webp). Currently, there are no parameters for output quality, but if you really need it, you can use manual parameter tuning as a workaround. The HEIC quality factor only takes effect when importing heic/heif images. The screenshot function allows you to easily extract a cover from the video. By default, it will grab the playback progress of the 🎥 when you open the pop-up. You can choose to capture from the original or transcoded video, or just modify the timestamp value. This value will be used for the live photo component’s data-photo-time attribute, as well as the relevant fields in the XMP tags when creating a live photo.
🚩 The following modules are relatively independent. Click the module title to collapse/expand.
So, if you are using an OPPO series phone, you just need to switch to the corresponding XMP meta preset to export the correct live photo. Since I don’t have other brands of phones on hand, the adaptation plan has to be put on hold for now. However, I tried it out at an offline experience store, and both Xiaomi and Honor only export live photos from Xiaohongshu as two separate files, so I guess it will be even more difficult 🤔. Recently, ColorOS updated a video 🎥 feature, but it only allows a maximum of 3 seconds, while the live photos exported by MLPW have no time limit 😎.
If you import a live photo, MLPW will, by default, extract the embedded XMP fields into the input box. If the extraction fails, it will display the currently selected preset value. Clicking the in the upper right corner can clear the input box, and clicking ⟳ can restore the initial XMP data from when the image was loaded.
Authorization: Basic btoa(USERNAME:PASSWORD)
and Content-Type: application/xml
. Clicking the 💾 in the upper right corner can save the current server configuration (in JSON format), which will then appear in the API URL dropdown menu. The ⿻ button next to it is for importing and exporting configurations. If you have a valid configuration in your clipboard, it will directly write it to local storage or ask if you want to overwrite; if not, it will actively copy the current configuration to the clipboard, making it easy to migrate configurations between different devices.Currently, I have successfully tested 📌Junze’s Dooong public image host, 📌R2 Uploader, and 📌a PHP script. In theory, any standard RESTful API should be compatible. In the API URL, you can use
{filename}
to represent the filename, and in the request body, use {File}
to represent the uploaded file itself. The biggest challenge is still the cross-origin issue. A feasible solution is to compile it into a native App or use a CORS forwarding server 🖧 to solve it.
To make it easier to use the uploaded file links, a one-click copy filename button has also been arranged in the dropdown menu ✌.
Cloud conversion ☁️ is essentially using GET requests to access URL-based transcoding services. 📌Well-known public services like WebP Cloud Services and Cloudflare Image both offer a certain amount of free quota. Each free account gets 5000 free conversions per month, and it’s very simple to use:
https://image.yourdomain.com/raw.jpg
.https://image.yourdomain.com/cdn-cgi/image/format=webp,quality=75,fit=scale-down/raw.jpg
.To be able to explicitly specify the format after conversion, the final format to be filled into the API URL should look like this: https://image.yourdomain.com/cdn-cgi/image/format={webp},quality=75,fit=scale-down/{filename}
. Here, {filename}
will be replaced with the RAW filename, and {webp}
will be used as the suffix for the cloud-converted file.
After more than a month of learning and polishing, MLPW has, in my opinion, reached a usable state, so I wrote this article to share and document it. Of course, it still lacks compatibility testing for models other than OPPO 📱, and there may be some bugs hidden in special scenarios 🐞. Currently, the feature I use most is separating and compressing live photos taken with my phone, and then uploading them to my blog as an image host. In the future, the feature I most want to add is cropping , to achieve a cool media editing effect similar to the web version of 𝕏.