December 6, 2017

How to export video from motion photo in Samsung S7/S8 using a bash script?

Samsung Galaxy S7 and S8 phones have a new way to capture pictures called Motion Photo. When shot in this mode, with each picture, it also records a short video before the picture was captured.

You can view this short video when you view your pictures using the Gallery app of the phone, but when you backup these pictures to your computer, you lose access to them. Below, I will explain a solution which you can use to extract these videos. You basically need a terminal from which you can run grep, cut and tail.

Logic

Logic is quite simple. The video and the photo are stitched on the same file. If you open the picture using a hex editor, towards the end of the file, you will see a portion of binary data that starts with text MotionPhoto_Data which contains the video.

Picture showing MotionPhoto_Data text in a file

Step 1

So, step 1 is to locate the position of this text. You can find this as follows.

grep -abo "MotionPhoto_Data" ./path/to/picture.jpg | cut -d: -f1

The flags specified in the grep mean the following:

  • -a process the binary of the file as text
  • -b prints the byte offset
  • -o prints out matching text

It’s trying to extract the byte offset of the file where MotionPhoto_Data can be found. Then, cut is used to remove other extra bits from the matched text so we can have only the number of offset.

Step 2

Next step is to extract all the data from the file after the position found in step 1. Let’s assume it was 8000. Then, the position we want to extract from is after the text MotionPhoto_Data which is 16 characters long, so from 8017. Then, in our terminal, we can do the following to extract the video

tail -c +8017 ./path/to/picture.jpg > ./path/to/picture.mp4

And, that’s it. Now, you can open your video.

Tool

I have wrapped all this logic into a small script, which can be downloaded and used instantly.

Repository: https://github.com/starx/SamsungMotionPhotoVideoExtractor

Install the script, with the following command

# curl -o /usr/local/bin/extractVideo_SamsungMotionPhoto.sh https://raw.githubusercontent.com/starx/SamsungMotionPhotoVideoExtractor/master/extractVideo_SamsungMotionPhoto.sh
# chmod +x /usr/local/bin/extractVideo_SamsungMotionPhoto.sh

And extract all the videos in a path, using the following command.

extractVideo_SamsungMotionPhoto.sh /path/to/pictures
September 20, 2016

How do I know when my docker mysql container is up and mysql is ready for taking queries?

Haren’s Question:

I am deploying a few different docker containers, mysql being the first one. I want to run scripts as soon as database is up and proceed to building other containers. The script has been failing because it was trying to run when the entrypoint script, which sets up mysql (from this official mysql container), was still running.


sudo docker run --name mysql -e MYSQL_ROOT_PASSWORD=MY_ROOT_PASS -p 3306:3306 -d mysql
[..] wait for mysql to be ready [..]
mysql -h 127.0.0.1 -P 3306 -u root --password=MY_ROOT_PASS < MY_SQL_SCRIPT.sql

Is there a way to wait for a signal of an entrypoiny mysql setup script finishing inside the docker container? Bash sleep seems like a suboptimal solution.

EDIT: Went for a bash script like this. Not the most elegant and kinda brute force but works like a charm. Maybe someone will find that useful.


OUTPUT="Can't connect"
while [[ $OUTPUT == *"Can't connect"* ]]
do
OUTPUT=$(mysql -h $APP_IP -P :$APP_PORT -u yyy --password=xxx < ./my_script.sql 2>&1)
done

On your ENTRYPOINT script, you have to check if you have a valid MySQL connection or not.

This solution does not require you to install a MySQL Client on the container and while running the container with php:7.0-fpm running nc was not an option, because it had to be installed as well. Also, checking if the port is open does not necessarily mean that the service is running and exposed correctly. [more of this]

So in this solution, I will show you how to run a PHP script to check if a MySQL Container is able to take connection. If you want to know why I think this is a better approach check my comment here.

File entrypoint.sh

#!/bin/bash
cat << EOF > /tmp/wait_for_mysql.php
<?php
$connected = false;
while(!$connected) {
    try{
        $dbh = new pdo( 
            'mysql:host=mysql:3306;dbname=db_name', 'db_user', 'db_pass',
            array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
        );
        $connected = true;
    }
    catch(PDOException $ex){
        error_log("Could not connect to MySQL");
        error_log($ex->getMessage());
        error_log("Waiting for MySQL Connection.");
        sleep(5);
    }
}
EOF
php /tmp/wait_for_mysql.php
# Rest of entry point bootstrapping

By running this, you are essentially blocking any bootstrapping logic of your container UNTIL you have a valid MySQL Connection.

...

Please fill the form - I will response as fast as I can!