Solve React Native custom shell script stuck for long time in Xcode

Disclaimer, I develop React Native app in Windows platform and Android version first. For iOS version, compile in Xcode is my last process for testing or deploy. So the following tip may not suitable for your case.

Each time, when build React Native app in Xcode, no matter it is build for simulator or device, the long building time is a painful waiting process.

It stuck at custom shell script process, which is running ../node_modules/react-native/scripts/react-native-xcode.sh

This script compile js files together for embed in the app and it takes a very long time for scan through all node_modules

Since I develop in Windows platform, I can use this command to package js files faster react-native bundle --dev false --entry-file index.ios.js --bundle-output ios/main.jsbundle --platform ios

In Xcode, I can skip this custom shell script process by tick Run script only when installing, it will disable react-native-xcode.sh actually, file main.jsbundle will not include in the app and the app cannot run.

So we have to include the main.jsbundle by add them to Copy Bundle Resources

Build the app again, you will find the compile speed is much faster now.

If you have (new added) image files, this trick will not bundle the image files into app, so please go through the normal process first. This trick is for update js files only.

Config Raspberry Pi for auto-login, disable Alt+F4, Ctrl+Alt+Del keys, auto-run python code

Just finished the first job on Raspberry Pi, using python code as a kiosk program, some common config you may needed:

My Raspberry Pi is running with RASPBIAN Debian Wheezy

Auto-login
After boot up the Raspbian, if you want to auto-login with username: pi, password: raspberry.
sudo nano /etc/inittab
find:
1:2345:respawn:/sbin/getty --noclear 38400 tty1
change to:
1:2345:respawn:/bin/login -f pi tty1 dev/tty1 2>&1

My job has keyboard connect, to prevent user press the unwanted keys.
Disable Ctrl+Alt+Del keys
find:
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
disable it by comment the above line (add # in the front of the line)
#ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

User can also use key combine Alt+F1…Alt+F6 to switch between different consoles, to disable it and stay on one console only:
Disable multiple virtual consoles
Comment the following lines:
#2:23:respawn:/sbin/getty 38400 tty2
#3:23:respawn:/sbin/getty 38400 tty3
#4:23:respawn:/sbin/getty 38400 tty4
#5:23:respawn:/sbin/getty 38400 tty5
#6:23:respawn:/sbin/getty 38400 tty6

save it and then type:
sudo nano /etc/default/console-setup
find 1-6 and change to 1-1
ACTIVE_CONSOLES="/dev/tty[1-1]"

Auto-run python code
sudo nano /etc/profile
add the below line to the end:
sudo python /home/pi/yourcode.py

After finished all above config, reboot:
sudo reboot

First Try on Erlyvideo

Erlyvideo is another free/commercial Flash Media Server alternative, I notice it because it claimed it can streaming video to iPhone. I am looking for a solution directly streaming flv to iPhone for a long time, but still cannot find any.

Movie file location setting
Edit erlyvideo/priv/erlyvideo.conf, parameter: file_dir

iPhone streaming path
http://www.<domain>.com:8082/iphone/playlists/<folder>/<folder>/<filename.ext>.m3u8

Testing result: mp4, mp3 can stream in iPhone successfully, but mp3 playing is not smooth. flv can produce segment file, but cannot play in iPhone.

Abbreviate TextField Characters According to Rows Count

Before AS3, we can only use substr to abbreviate string characters number for TextField, but we have to guess a extract number to fit our UI design, e.g. only show two lines, we have to guess in this font size, font face, what is maximum numbers of character can be shown. It is a problem which is hard to solve for a long time.

When come to AS3, TextField class have a new method call getLineLength(), it can return each line, number of characters are shown. So I have written this small class to help me limit the number of rows can be shown in TextField

Download MaxRowsTextField class file
Download demo source

Usage
This class is extended from TextField class:
var tf:MaxRowsTextField = new MaxRowsTextField();
tf.width = 290;
tf.multiline = tf.wordWrap = true;

// 0 mean unlimited, default is 0
tf.maxRows = 4;

// change abbreviate symbol, default is "..."
tf.moreStr = "...(more) ";

// if you want to limit rows count, use this, otherwise, you can just use text or htmlText
tf.text2 = "This is a vey long message";

This class is extracted and simplified from my VCASMO 2.0 project.

Flash Player 10.1, Client-side Microphone Recording Demo

Thanks Flash Player 10.1, now we can record the sound through microphone directly in browser without the use of Flash Media Server, you can download the wav file converted from ByteArray immediately, you can download mp3 which I send wav file to server and using LAME to encode as mp3. Hope AS3 mp3encoder can come out in one day, then a pure client side microphone recording dream will come true since Flash Player 6!

[Demo]

To learn how to use microphone to record sound, you can check this devnet article.

Trouble with Hotlink Protection and HTTP Referer in Different Browsers

To save bandwidth, most of servers will practice some hotlink protection, usually using either following script to check whether the HTTP referer is come from the same server, most script are focus on image file, but it can slightly modified for FLV protection. There are two common methods to do that:

Edit in .htaccess RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC]
RewriteRule \.(flv|mp3)$ - [NC,F,L]

Edit in httpd.conf, first enabled this:
LoadModule setenvif_module modules/mod_setenvif.so
then put it inside <VirtualHost>, just before </VirtualHost>
SetEnvIfNoCase Referer "^http(s)?://(www\.)?yourdomain.com(/|$)" local_ref=1
SetEnvIfNoCase Referer "^$" local_ref=1
<FilesMatch "\.(flv|mp3)">
Order Allow,Deny
Allow from env=local_ref
</FilesMatch>

However, FLV need to play through Flash Player, different browsers and even minor versions handle plugin HTTP referer differently, so it make such hotlink protection through HTTP referer means impossible 🙁

Browser sends the URL of the requesting plug-in (i.e. the best situation, url of SWF) does not send a referer sends the embedding page URL
IE X    
Firefox   X  
Safari (MAC)     X
Safari (Win)   X  
<Chrome 3     X
Chrome 3+ X    
<=Opera 9     X
Opera 10+ X    

The hotlink protection cause problem when you let other people embed your video player in their site (like Youtube do), from the above table, you can find the third column will not work, for example in safari (MAC), the video cannot play because Apache think the FLV is linked by third party website and forbid FLV to be accessed.

Some installation notes on Flash Media Server 3/3.5

Port 80 Issue
FMS 3.5 comes with Apache, since server installed Apache, so do not install it. I want HTTP Tunneling, so chose Port 1935,80 during installation. When FMS started, Apache cannot run, because port 80 is listened by FMS now. Therfore if you get one server only, running web server and FMS, cannot use HTTP Tunneling. You can edit conf\fms.ini
ADAPTOR.HOSTPORT = :1935

Becareful 19350
When study conf\_defaultRoot_\Adaptor.xml, found one line:
<HostPort name="edge1" ctl_channel="localhost:19350">
Why it is 19350, I thought that it was my careless to modify it before, so I changed to 1935, and then even FMS is running, but cannot connect to any applications

Convenient VOD and Virtual Directory
FMS 3.0 comes with a very convenient applications “vod”, it is for streaming video, you can just put FLV under applications\vod\media\, connect to rtmp:/vod, then it can stream video. vod support virtual directory, you can edit applications\vod\Application.xml, under <VirtualDirectory> add new node:
<Streams>/test;C:\Video</Streams>
Suppose a FLV at C:\Video\folder1\video_1.flv, you can code like that:
var my_nc:NetConnection = new NetConnection();
my_nc.connect("rtmp:/vod");
var my_ns:NetStream = new NetStream(my_nc);
my_video.attachVideo(my_ns);
my_ns.play("test/folder1/video_1");