Wednesday, 16 October 2019

Fixing Corrupted Video Captured by Samsung Galaxy Note 8 Android Pie 9

Many of us have experienced getting corrupted videos when using recording features of our phones or cameras. The causes of this annoying experience come from various sources: faulty Micro SD cards, errors in camera software, flat batteries, etc.

I own 2 Android phones, Motorola XT720 (Android 2.3) and Samsung Galaxy Note 8 (Android 9.0). Both have shown faults related to Micro SD cards. A couple of days ago, I recorded a 30 minutes video using the default camera app of my Samsung Galaxy Note 8. The SD card was then shown as corrupted in the phone storage management system. My recorded video now is just a file without extension in the SD card, 'temp_video'. This file is not viewable in any popular video viewers including the powerful VLC media player. Luckily, the Micro SD card is perfectly accessible on my computer.

I looked around on the Internet to find a quick and cheap way to recover my video from the corrupted file temp_video. Based on what I read, the content of the video is actually captured in the temp_video file. The most common reason that the file is not readable is the missing metadata associated to the file. This metadata may include the information about the camera and format of the video (e.g., mp4). Luckily this metadata can be retrieved from the non corrupted video files taken from the same device. In my case, the other successfully recorded videos by my Galaxy Note 8 are all in mp4 format.

I have successfully recovered my video using the software Do-It-Yourself Video Repair Tool (VRT). The free version of the software only recovers half of the video. The trick to overcome this limitation is to make a copy of your file and combine the two files into one file. This way, half of the file is basically your full video. Different operating systems have different free tools for concatenating files together into one file. If you have access to Windows computer you can use this CMD command line to combine two files.

copy /b temp_video + temp_video_copy.mp4 temp_video_double.mp4

I have shown you how to 'trick' the free version of the VRT software. But if you have many corrupted videos or you plan to use the software VRT often, please consider to pay for the software to support its developers. By purchasing the software, you also can save the time and effort to clone and combine corrupted files with the technique that I described above. I would also like to say thank you for the questions and answers in this online discussion.

My final advice for fellow Android users is that the SD cards are not reliably managed by Android phones. I decided to only use the internal storage of my Samsung Galaxy Note 8 from now to avoid future issues with the external storage and Android. My Micro SD card is perfectly fine; after taking out all the photos and videos, I have formatted it with the standard SD Memory Card Formatter (by the SD Association) to use for other purposes.

Thursday, 11 July 2019

AI, Cats and Humanity

Philosophical corner: Humans seem to recognize artificial objects better than natural things. For example, it seems to be easier to distinguish different types of vehicles than to group different types of trees or bugs. The reason for this could be that our brains choose to learn about the items that are more important for our daily activities; and most artificial items (except for some such as artworks) are invented to support such activities.

Artificial intelligence (AI) (e.g., image recognition computational models) is not like that, it is not as picky as human brain is; it absorbs as much available information as it can. The advantage of this action is that a broader range of knowledge is learnt by an AI. Fortunately, we have been flooding our digitized knowledgebase with millions of cat pictures. The poor AI will just spend all day long learning this information. Therefore, cats are the saviours of humanity. Let’s follow @me-animal for more cat pictures.

Monday, 3 June 2019

MongoDB essentials: Setup and basic operations

MongoDB is a popular NoSQL database management system that is often used in the servers of modern applications. This blogpost shows the essentials of working with MongoDB.
  1. Setup MongoDB in Ubuntu
    sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
    echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
    sudo apt-get update
    sudo apt-get install -y mongodb-org
  2. Start/Stop MongoDB server
    //Start
    sudo service mongod start
    //Check status and get the PID
    service mongod status
    //Check if mongodb is running
    ps -aux | grep 16822
    //Check if mongodb server is listening at default port 27017
    netstat -tulnp | grep 2701
    //Stop
    sudo service mongod stop
    //Restart
    sudo service mongod restart
  3. Essential operations
    //Start Mongo Shell
    mongo
    //List all databases
    show dbs
    // Switch current database to DB_NAME. The mongo shell variable db is set to the current database.
    use DB_NAME
    //Print a list of users for current database
    show users
    //Print a list of all roles, both user-defined and built-in, for the current database
    show roles
    //Create database
    use mynewdb
    db.users.insert({ id: 1 })
    //Drop database
    db.dropDatabase()
    //Create a new collection in the current database
    db.createCollection("NewCollectionName")
    //Print a list of all collections for current database
    show collections
    //Add new document to a collection
    db.COLLECTION_NAME.insert(document)
    //Query document
    db.COLLECTION_NAME.find(condition)
    example: db.users.find({"id": 1001})
    //Show all documents
    db.COLLECTION_NAME.find();
    //Update document
    db.users.update(CONDITION, UPDATED DATA, OPTIONS)
    //Delete document
    db.COLLECTION_NAME.remove(CONDITION)
    //More SQL liked MongoDB commands
    LINK

Saturday, 1 June 2019

Your Bitbucket repository reaches 2GB limit: Don't panic!


There are soft limit of 1GB and hard limit of 2GB for a git repository hosted in Bitbucket. After it reaches 2GB, the repository becomes read only and you cannot perform any new push.

In many situations, there may be large garbage in your git repository and all you need to do is to run the built-in garbage collector on Bitbucket server.

You can contact Bitbucket support to run the garbage collector for you. Or you can trigger the process yourself by creating a new dummy branch and remove it. There would be a decent chance that your repository size would reduce after this process. I have successfully reduced my repository size from 2.04 GB down to 623.4 MB with this approach!

If the size of your repository is still larger than 2GB, you should start thinking about Git Large File Storage as well as techniques to reduce your repository size as described in this official link

Thursday, 30 May 2019

Set a git project up and running quickly (Host in GITLAB or GITHUB)


  1. Create a new repository with README file in GITLAB or GITHUB websites. 
  2. Inside GITLAB or GITHUB web interfaces, copy the link under Clone with HTTPS.
  3. In you local development machine, navigate to the folder where you want to put your project folder inside (e.g., ALL_GIT_PROJECTS).
  4. Run the following command line to clone your repository to a new folder in the folder ALL_GIT_PROJECTS

  5. git clone [LinkToYourGitlabOrGithubRepository] [NameOfLocalFolderWhereTheRepoWillStay]
  6. Enter your username and password, then wait for your remote repository to be downloaded into your local project folder. Your project folder can now be managed in GIT. Navigate to your project folder and try the following commands.

  7. git status
    git log --oneline

Saturday, 25 May 2019

A small tip to improve productivity in doing repetitive tasks


Hello everyone, in this blog post I would like to share with you my experience in improving the productivity in doing some certain repetitive tasks. 

Today, I was working on converting a bunch of files from one format to the other format, and there are multiple steps for converting each file. For example the whole job is to perform a sequence of (task 1 -> task 2 -> task 3) repetitively n number of times. 

Of course, if the tasks are scriptable and the effort to write the script is small, then go for it. But not everything is scriptable. Also, if you have more than one person then doing the pipeline strategy is definitely the best way to handle these jobs. 

When the tasks are not scriptable and you only have yourself, then doing the first task n number of times before moving on to the second task for n number of times is a better strategy than finishing the sequence task 1, task 2, task 3 then go back to task 1 for the next round. The reason is that you utilize the short term memory and muscle memory to finish all task 1 repeatedly n times instead of switching your brain and muscle from task 1 to task 2 then task 3 and then back to task 1 again. 

Overall, when you encounter these situations, my advice is to examine the productivity of your process and see if there is room for improvement. The effort in thinking a better strategy to improve your productivity is always worth it. 

Tuesday, 21 May 2019

Try cooking rice in a 940ml microwavable noodle container

Hello everyone, today I bought a new small microwavable noodle container to prepare some quick rice for lunch at work.


I have cooked rice in a microwave before, but with a proper big container designed for cooking rice. So it was quite excited for me to try making rice with this small container. 


I have put a small amount of rice in the container (probably about three quarters of a cup). I rinsed the rice with water a few times and added hot water in. Again, since I did not have a cup measure with me, I estimated everything.


Just one quick note, when you close the lid of the container, remember to leave the vent open. This step is very important for cooking rice.


I put the container into the microwave and heated it for 10 minutes. After this, I had to add some more water and heated it for another 3 minutes.

The rice turned out okay. I put some pieces of chopped chicken breast in and microwaved it for another 2 minutes. Finally, I added some vegetables and chilli sauce and my meal was ready to serve!




Overall, the advantages of this container are that it is small and easy to clean. Its size is also nice enough to be used directly as a bow, so you do not have more unnecessary things to carry and wash. The rice also turns out okay. The main disadvantage is that some rice steam may spew onto the microwave plate due to the small size of the noodle container, so you may need to clean it after.


Kotlin for Android development essentials: TabLayout for ViewPager

In the previous blog post (link) I have shown you how to use ViewPager to change Fragment with swipe gesture. In this blog post, I will show you how to add tab layout to indicate which fragment is being shown.

You only need to make some small changes to three files.

Firstly, add the following line to the dependencies block of build.gradle.
implementation 'com.android.support:design:28.0.0'


Secondly, add the TabLayout to the ViewPager view in the layout file of main activity (activity_main.xml) like the following.

Finally, add the following function to the ViewPagerAdapter class in ViewPagerAdapter.kt.
override fun getPageTitle(position: Int): CharSequence? {
     return (position+1).toString()
}


That is all! Just compile and run our app with beautiful tab layout at the top!!!




Kotlin for Android development essentials: ViewPager and Fragment

One of the common features in Android applications is swiping to change texts, images, buttons or complex combinations of those. In today's tutorial, I will show you how to do that in Kotlin programming language and Android studio 3.4.1.

Firstly, create a blank Android project (remember to choose Kotlin as the language) with an empty main activity; there will be two files created, MainActivity.kt for the activity and activity_main.xml for the layout of the activity.

To be able to swipe to change fragment (you can put texts, images, buttons, etc into a fragment), we need add view android.support.v4.view.ViewPager as a place holder of the fragment. We then can pass the fragment that we want to render to the ViewPager adapter which is linked to the ViewPager view.

Let's start by creating the layout for the main activity with ViewPager view on top of a simple text view. The layout code for the main activity is shown below.

The next step is to create the image fragment that shows the name of an image. There will be two files created, ImagesFragment.kt for the fragment and fragment_images.xml for the layout of the fragment. The image fragment class can be used to return a new image fragment instance with a new image name as the input parameter; this input parameter is then used to change the content of the only text view inside the image fragment. It is important to know that a fragment needs to be inflated to a view in onCreateView function before its children views (e.g., a text view in our case) can be accessed in onViewCreated function. Let's have a look at the image fragment class and layout.

The next step is to create the ViewPager adapter to control which fragment will be rendered in the ViewPager view. It is important to know that there are two types of adapters for different situations, FragmentPagerAdapter (fragments are stored in memory until the activity shuts down) and FragmentStatePagerAdapter (fragments that user does not see are destroyed). The source code for the adapter is shown below.

The final step is to go back to the main activity and create the link between the ViewPager view and the ViewPager adapter. The source code for this step is shown below.

Our app is ready to run now!!!

Friday, 17 May 2019

Two best ways to write code snippets in Blogger

In this blog post, I present two approaches to write code snippets in Blogger platform. The advantages and disadvantages of each method are also discussed.

The first method is to create a CSS class for code snippets and apply this CSS class to your blog. You first go to Blogger Dashboard -> Theme -> Customise -> Advanced -> Add CSS, then put the following CSS code into the Add Custom CSS text box.
.code { background:#f5f8fa; background-repeat:no-repeat; border: solid #5C7B90; border-width: 1px 1px 1px 5px;
color: #000000; font: 12px 'Courier New', Courier, monospace; line-height: 16px;
margin: 5px 0px 5px 0px; padding: 0px 5px 5px 0px; max-height: 200px; min-height: 16px;
overflow: scroll; white-space: nowrap; width: 98%; }.code:hover { background-repeat:no-repeat; }

Finally, you click on Apply to Blog button. From now on, you can write your code snippets in between the following div tag. The above and below code snippets themselves are shown using this method.
<div class='code'>
</div>


The second method is to host your code snippet as a public in GIST in gist.github.com if you have a Github account. Then you can link it back to your blog post using the generated embed script that looks similar to the following one.
<script src="https://gist.github.com/catcancode/994366af60f7b2d1d66dd3eb05b35a7e.js"></script>

The result of the above embed script is shown below.

Overall, the first method is convenient and suitable for small code snippets. You do not need to get out of your Blogger post composing environment just to show a small code snippet using method one. On the other hand, the second method requires you to have a Github account and you need to create a new gist for any new code snippet that you want to include in your blog post. However, the second method produces syntax-aware highlighted code for many languages. Therefore, if you want to show long code snippets, the second method will produce more readable code.
Because of the above reasons, I still use both methods of showing code snippets in my Blogger post depending on different situations.