Streaming 1080P video using Raspberry Pi (or BeagleBone Black)

datePosted on 21:24, November 9th, 2013 by Many Ayromlou

I’ve finally got this project to a point were I can do a write up on it. The following hardware is needed:

  1. Raspberry Pi 512K version (or BeagleBone Black)
  2. Logitech C920 Webcam
  3. 16 GB micro SDHC card (can probably do it on 8GB too)
  4. Wireless dongle supported by linux (I’m using a TrendNet TEW-645UB which was pretty much plug and play)

The goal of this project is to get the following installed and configured:

  1. CRTMP streaming server
  2. C920 install and config (v4l2), ffmpeg installation, boneCV installation from Derek Molloy’s site
  3. configuring ddclient for dynamic DNS (optional)
  4. putting it all together and creating a webpage with embedded JWplayer to view the stream

UPDATE: Sound works now on BeagleBone Black. On Raspberry you will run into alsa buffer xruns. See below for updated streamVideoRTSP script.

What I still need to figure out is the sound off the camera. At the moment I got buttery smooth 1080P video off the Pi (on wired or wireless connection) running at 5Mb/s but the sound is yet to come.

0) Preparation:

So to prepare you need to get linux installed on your Pi or BBB (BeagleBone Black). I used the latest raspbian for the PI and BeageBone Black Ubuntu Raring 13.04 for BBB. Get it installed onto your SD card. If you use a larger than 8GB SD card you can follow the procedure below to expand the partition from 8GB to whatever your SD card can hold (mine is a 16GB card) (NOTE: almost all commands need to be executed as root so do a sudo -i to start with):

  • Use fdisk to see the partition table
    root@debian-armhf:/# fdisk /dev/mmcblk0
    
    Command (m for help): p
    
    Disk /dev/mmcblk0: 3947 MB, 3947888640 bytes
    4 heads, 16 sectors/track, 120480 cylinders, total 7710720 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x80000000
    
            Device Boot      Start         End      Blocks   Id  System
    /dev/mmcblk0p1   *        2048        4095        1024    1  FAT12
    /dev/mmcblk0p2            4096     3751935     1873920   83  Linux
  • In this case we’re expanding partition 2 by first deleting it and without writing the partition table recreating it to span the entire disk (and then writing the new partition table to SD card). This in effect expands the partition. We will expand the filesystem after reboot.
    Command (m for help): d
    Partition number (1-4): 2
    
    Command (m for help): p
    
    Disk /dev/mmcblk0: 3947 MB, 3947888640 bytes
    4 heads, 16 sectors/track, 120480 cylinders, total 7710720 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x80000000
    
            Device Boot      Start         End      Blocks   Id  System
    /dev/mmcblk0p1   *        2048        4095        1024    1  FAT12
    
    Command (m for help): 
    Command (m for help): n
    Partition type:
       p   primary (1 primary, 0 extended, 3 free)
       e   extended
    Select (default p): p
    Partition number (1-4, default 2): 2
    First sector (4096-7710719, default 4096): 
    Using default value 4096
    Last sector, +sectors or +size{K,M,G} (4096-7710719, default 7710719): 
    Using default value 7710719
    
    Command (m for help): p
    
    Disk /dev/mmcblk0: 3947 MB, 3947888640 bytes
    4 heads, 16 sectors/track, 120480 cylinders, total 7710720 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x80000000
    
            Device Boot      Start         End      Blocks   Id  System
    /dev/mmcblk0p1   *        2048        4095        1024    1  FAT12
    /dev/mmcblk0p2            4096     7710719     3853312   83  Linux
    
    Command (m for help): 
    Command (m for help): w
    
    The partition table has been altered!
    
    Calling ioctl() to re-read partition table.
    
    WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
    The kernel still uses the old table. The new table will be used at
    the next reboot or after you run partprobe(8) or kpartx(8)
    Syncing disks.
    root@debian-armhf:/# reboot
  • Once you’re back from reboot we need to expand the filesystem to cover the new partition. Don’t forget to sudo -i to become root.
    root@debian-armhf:/# df
    Filesystem     1K-blocks   Used Available Use% Mounted on
    rootfs           1811704 740184    977824  44% /
    /dev/root        1811704 740184    977824  44% /
    devtmpfs          253920      0    253920   0% /dev
    tmpfs              50816    216     50600   1% /run
    tmpfs               5120      0      5120   0% /run/lock
    tmpfs             101620      0    101620   0% /run/shm
    /dev/mmcblk0p1      1004    474       530  48% /boot/uboot
    root@debian-armhf:/# 
    
    root@debian-armhf:/# resize2fs /dev/mmcblk0p2 
    resize2fs 1.42.5 (29-Jul-2012)
    Filesystem at /dev/mmcblk0p2 is mounted on /; on-line resizing required
    old_desc_blocks = 1, new_desc_blocks = 1
    The filesystem on /dev/mmcblk0p2 is now 963328 blocks long.
    
    root@debian-armhf:/# df
    Filesystem     1K-blocks   Used Available Use% Mounted on
    rootfs           3761680 741096   2851404  21% /
    /dev/root        3761680 741096   2851404  21% /
    devtmpfs          253920      0    253920   0% /dev
    tmpfs              50816    216     50600   1% /run
    tmpfs               5120      0      5120   0% /run/lock
    tmpfs             101620      0    101620   0% /run/shm
    /dev/mmcblk0p1      1004    474       530  48% /boot/uboot
    root@debian-armhf:/# 

1) CRTMP Server installation

CRTMP server is a streaming media server very similar to wowza. I use this to point ffmpeg at and to get playback on JWplayer. Grab the source code and follow the instructions for installing it on Ubuntu from http://wiki.rtmpd.com/quickbuild. You will need to create your build environment before you start building so do the command below to setup your environment and get the prerequisites installed:

  • Install needed packages
    root@ubuntu-armhf:/# apt-get install g++ subversion cmake make libssl-dev
  • Run these two additional commands
    root@ubuntu-armhf:/# apt-get install libcurl4-openssl-dev pkg-config
    root@ubuntu-armhf:/# pkg-config openssl --cflags --libs
  • Make sure that the last commands output was “-lssl -lcrypto”
  • Fetch the latest repo version of CRTMP
    cd /opt
    svn co --username anonymous --password "" https://svn.rtmpd.com/crtmpserver/trunk crtmpserver
    cd /crtmpserver/builders/cmake/cmake_find_modules
  • Edit the file Find_openssl.cmake and add the following path to the PATHS section of ssl, crypto and z sections above /usr/lib64 line:
    /usr/lib/arm-linux-gnueabihf
  • Edit the file Find_pcap.cmake and add the following path to the PATHS section of pcap sections above /usr/lib64 line:
    /usr/lib/arm-linux-gnueabihf
  • Edit the file Find_dl.cmake and add the following path to the PATHS section of dl sections above /usr/lib64 line:
    /usr/lib/arm-linux-gnueabihf
  • Edit the file Find_lua.cmake and add the following path to the PATHS section of lua sections above /usr/lib64 line:
    /usr/lib/arm-linux-gnueabihf
  • Might have to do this if locale is giving you grief (Note: I’ve picked en_CA since I live in Canada, you need to pick the right one for your country/region):
    root@ubuntu-armhf:/opt/crtmpserver/builders/cmake/cmake_find_modules# sudo locale-gen en_CA en_CA.UTF-8
    
    Generating locales...
    
    en_CA.ISO-8859-1... done
    
    en_CA.UTF-8... done
    
    Generation complete.
    
    root@ubuntu-armhf:/opt/crtmpserver/builders/cmake/cmake_find_modules# dpkg-reconfigure locales
    
    Generating locales...
    
    en_CA.ISO-8859-1... up-to-date
    
    en_CA.UTF-8... up-to-date
    
    en_US.UTF-8... done
    
    Generation complete.
  • Start building crtmp
    root@ubuntu-armhf:/opt/crtmpserver/builders/cmake# ./run
    
  • This process will take a while……go have a couple of coffee’s and/or snacks

Once this process is finished you’ll end up with the executable in /opt/crtmpserver/builders/cmake/crtmpserver, but that’s not how you run it. First you need a config file — you can edit crtmpserver.lua in /opt/crtmpserver/builders/cmake/crtmpserver or save a copy of the original and create a new one with the content from below (I’ve just cleaned up the original a tiny bit).

-- Start of the configuration. This is the only node in the config file. 
-- The rest of them are sub-nodes
configuration=
{
	-- if true, the server will run as a daemon.
	-- NOTE: all console appenders will be ignored if this is a daemon
	daemon=false,
	-- the OS's path separator. Used in composing paths
	pathSeparator="/",

	-- this is the place where all the logging facilities are setted up
	-- you can add/remove any number of locations

	logAppenders=
	{
		{
			-- name of the appender. Not too important, but is mandatory
			name="console appender",
			-- type of the appender. We can have the following values:
			-- console, coloredConsole and file
			-- NOTE: console appenders will be ignored if we run the server
			-- as a daemon
			type="coloredConsole",
			-- the level of logging. 6 is the FINEST message, 0 is FATAL message.
			-- The appender will "catch" all the messages below or equal to this level
			-- bigger the level, more messages are recorded
			level=6
		},
		{
			name="file appender",
			type="file",
			level=6,
			-- the file where the log messages are going to land
			fileName="/tmp/crtmpserver",
			--newLineCharacters="\r\n",
			fileHistorySize=10,
			fileLength=1024*256,
			singleLine=true
		}
	},

	-- this node holds all the RTMP applications
	applications=
	{
		-- this is the root directory of all applications
		-- usually this is relative to the binary execuable
		rootDirectory="applications",

		--this is where the applications array starts
		{
			-- The name of the application. It is mandatory and must be unique 
			name="appselector",
			-- Short description of the application. Optional
			description="Application for selecting the rest of the applications",

			-- The type of the application. Possible values are:
			-- dynamiclinklibrary - the application is a shared library
			protocol="dynamiclinklibrary",
			-- the complete path to the library. This is optional. If not provided, 
			-- the server will try to load the library from here
			-- //lib.{so|dll|dylib}
			-- library="/some/path/to/some/shared/library.so"

			-- Tells the server to validate the clien's handshake before going further. 
			-- It is optional, defaulted to true
			validateHandshake=false,
			-- this is the folder from where the current application gets it's content.
			-- It is optional. If not specified, it will be defaulted to:
			-- //mediaFolder
			-- mediaFolder="/some/directory/where/media/files/are/stored"
			-- the application will also be known by that names. It is optional
			--aliases=
			--{
			--	"simpleLive",
			--	"vod",
			--	"live",
			--},
			-- This flag designates the default application. The default application
			-- is responsable of analyzing the "connect" request and distribute 
			-- the future connection to the correct application.
			default=true,
			acceptors = 
			{
				{
					ip="0.0.0.0",
					port=1935,
					protocol="inboundRtmp"
				},
				{
					ip="0.0.0.0",
					port=8081,
					protocol="inboundRtmps",
					sslKey="server.key",
					sslCert="server.crt"
				},
				{
					ip="0.0.0.0",
					port=8080,
					protocol="inboundRtmpt"
                },
			}
		},
		{
			description="FLV Playback Sample",
			name="flvplayback",
			protocol="dynamiclinklibrary",
			aliases=
			{
				"simpleLive",
				"vod",
				"live",
				"WeeklyQuest",
				"SOSample",
				"oflaDemo",
			},
			acceptors = 
			{
				{
					ip="0.0.0.0",
					port=6666,
					protocol="inboundLiveFlv",
					waitForMetadata=true,
				},
				{
					ip="0.0.0.0",
					port=9999,
					protocol="inboundTcpTs"
				},
				{
					ip="0.0.0.0",
					port=10000,
					protocol="inboundUdpTs"
				},
				--[[{
					ip="0.0.0.0",
					port=7654,
					protocol="inboundRawHttpStream",
					crossDomainFile="/tmp/crossdomain.xml"
				}, ]]--
				{
					ip="0.0.0.0",
					port=554,
					protocol="inboundRtsp"
				},
			},
			externalStreams = 
			{
				--[[
				{
					uri="rtsp://fms20.mediadirect.ro/live2/realitatea/realitatea",
					localStreamName="rtsp_test",
					forceTcp=true
				},
				{
					uri="rtmp://edge01.fms.dutchview.nl/botr/bunny",
					localStreamName="rtmp_test",
					swfUrl="http://www.example.com/example.swf",
					pageUrl="http://www.example.com/",
					tcUrl="rtmp://edge01.fms.dutchview.nl/botr/bunny", --this one is usually required and should have the same value as the uri
					emulateUserAgent="MAC 10,1,82,76",
				}
				{
                        		uri="rtsp://animalhousenc.dvrdns.org:554/streaming/channels/0",
                        		localStreamName="PoolSide",
                        		forceTcp=true
                		},
               		 	{
                       			 uri="rtsp://animalhousenc.dvrdns.org:556/streaming/channels/0",
                       			 localStreamName="BoneYard",
                       			 forceTcp=true
                		},
                		{
                       			 uri="rtsp://animalhousenc.dvrdns.org:557/streaming/channels/0",
                       			 localStreamName="BigPool",
                       			 forceTcp=true
                		},
               		 	{
                       			 uri="rtsp://192.168.1.186:554/mpeg4/media.amp?videocodec=h264&streamprofile=high",
                       			 localStreamName="nerd",
                       			 forceTcp=true
                		}, 
               		 	{
                       			 uri="rtsp://192.168.1.190:554/0",
                       			 localStreamName="leopard",
                       			 forceTcp=true
                		}, ]]--
			},
			validateHandshake=false,
			--enableCheckBandwidth=true,
			--[[authentication=
			{
				rtmp={
					type="adobe",
					encoderAgents=
					{
						"FMLE/3.0 (compatible; FMSc/1.0)",
						"My user agent",
					},
					usersFile="users.lua"
				},
				rtsp={
					usersFile="users.lua"
				}
			}, --]]
			mediaStorage = {
			--[[	namedStorage1={
					--this storage contains all properties with their
					--default values. The only mandatory property is
					--mediaFolder
					description="Some storage",
					mediaFolder="/Volumes/Storage/media/",
					metaFolder="/tmp/metadata",
					enableStats=false,
					clientSideBuffer=15,
					keyframeSeek=false,
					seekGranularity=0.1,
				},
				namedStorage2={
					mediaFolder="/Volumes/Storage/media/mp4",
					metaFolder="/tmp/metadata",
					seekGranularity=0.2,
					enableStats=true,
				},
				namedStorage3={
					mediaFolder="/Volumes/Storage/media/flv",
					metaFolder="/tmp/metadata",
				},
				{
					--this one doesn't have a name
					mediaFolder="/Volumes/Storage/media/mp3",
				} --]]
			},
		},
		{
			name="samplefactory",
			description="asdsadasdsa",
			protocol="dynamiclinklibrary",
			aliases=
			{
				"httpOutboundTest"
			},
			acceptors = 
			{
				{
					ip="0.0.0.0",
					port=8989,
					protocol="httpEchoProtocol"
				},
				{
					ip="0.0.0.0",
					port=8988,
					protocol="echoProtocol"
				}
			},
			validateHandshake=false,
			--default=true,
		},
		{
			name="vptests",
			description="Variant protocol tests",
			protocol="dynamiclinklibrary",
			aliases=
			{
				"vptests_alias1",
				"vptests_alias2",
				"vptests_alias3",
			},
			acceptors = 
			{
				{
					ip="0.0.0.0",
					port=1111,
					protocol="inboundHttpXmlVariant"
				}
			},
			validateHandshake=false,
			--default=true,
		},
		{
			name="admin",
			description="Application for administering",
			protocol="dynamiclinklibrary",
			aliases=
			{
				"admin_alias1",
				"admin_alias2",
				"admin_alias3",
			},
			acceptors = 
			{
				{
					ip="0.0.0.0",
					port=1112,
					protocol="inboundJsonCli",
					useLengthPadding=true
				},
			},
			validateHandshake=false,
			--default=true,
		},
		{
			name="proxypublish",
			description="Application for forwarding streams to another RTMP server",
			protocol="dynamiclinklibrary",
			acceptors =
			{
				{	
					ip="0.0.0.0",
					port=6665,
					protocol="inboundLiveFlv"
				},
			},
			abortOnConnectError=true,
			targetServers = 
			{
				--[[{
					targetUri="rtmp://x.xxxxxxx.fme.ustream.tv/ustreamVideo/xxxxxxx",
					targetStreamName="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
					localStreamName="stream1",
					emulateUserAgent="FMLE/3.0 (compatible; FMSc/1.0 http://www.rtmpd.com)"
				}]]--,
				--[[{
					targetUri="rtmp://gigi:spaima@localhost/vod",
					targetStreamType="live", -- (live, record or append)
					emulateUserAgent="My user agent",
					localStreamName="stream1",
					keepAlive=true
				},]]--
			},
			externalStreams = 
			{
				--[[{
					uri="rtsp://fms20.mediadirect.ro/live2/realitatea/realitatea",
					localStreamName="stream1",
					forceTcp=true,
					keepAlive=true
				},]]--
			},
			validateHandshake=false,
			--default=true,
		},
		{
			name="stresstest",
			description="Application for stressing a streaming server",
			protocol="dynamiclinklibrary",
			targetServer="localhost",
			targetApp="vod",
			active=false,
			--[[streams = 
			{
				"lg00","lg01","lg02","lg03","lg04","lg05","lg06","lg07","lg08",
				"lg09","lg10","lg11","lg12","lg13","lg14","lg15","lg16","lg17",
				"lg18","lg19","lg20","lg21","lg22","lg23","lg24","lg25","lg26",
				"lg27","lg28","lg29","lg30","lg31","lg32","lg33","lg34","lg35",
				"lg36","lg37","lg38","lg39","lg40","lg41","lg42","lg43","lg44",
				"lg45","lg46","lg47","lg48","lg49"
			},]]--
			streams = 
			{
				"mp4:lg.mp4"
			},
			numberOfConnections=10,
			randomAccessStreams=false
		},
		--[[{
			name="vmapp",
			description="An application demonstrating the use of virtual machines",
			protocol="dynamiclinklibrary",
			vmType="lua",
			script="flvplayback.lua",
			aliases=
			{
				"flvplayback1",
				"vod1"
			},
			acceptors=
			{
				{
					ip="0.0.0.0",
					port=6544,
					protocol="inboundTcpTs"
				}
			}
		},]]--
		--#INSERTION_MARKER# DO NOT REMOVE THIS. USED BY appscaffold SCRIPT.
	}
}

Once you have this saved (or modified yours to look like this you can go ahead and try to start the server with the following command (NOTE: you need to be in the cmake directory (rather than crtmpserver) and reference the files with partial paths……not sure why…..something to do with cmake base directory).

cd /opt/crtmpserver/builders/cmake/
./crtmpserver/crtmpserver ./crtmpserver/crtmpserver.lua

You should get output similar this this

/crtmpserver/src/crtmpserver.cpp:216 C++ RTMP Media Server (www.rtmpd.com) version 1.1_rc1 build 808 - Gladiator - (built on 2013-09-28T21:19:24.000)
/crtmpserver/src/crtmpserver.cpp:219 OS files descriptors count limits: 4096/4096
/crtmpserver/src/crtmpserver.cpp:221 Initialize I/O handlers manager: epoll without timerfd_XXXX support
/crtmpserver/src/crtmpserver.cpp:224 Configure modules
/crtmpserver/src/crtmpserver.cpp:230 Plug in the default protocol factory
/crtmpserver/src/crtmpserver.cpp:237 Configure factories
/thelib/src/configuration/module.cpp:97 Loaded factory from application samplefactory
/crtmpserver/src/crtmpserver.cpp:243 Configure acceptors
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 0->1 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 1->2 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 2->3 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 3->4 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 4->5 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 5->6 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 6->7 IOHT_UDP_CARRIER
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 7->8 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 8->9 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 9->10 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 10->11 IOHT_ACCEPTOR
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 11->12 IOHT_ACCEPTOR
/crtmpserver/src/crtmpserver.cpp:249 Configure instances
/crtmpserver/src/crtmpserver.cpp:255 Start I/O handlers manager: epoll without timerfd_XXXX support
/crtmpserver/src/crtmpserver.cpp:258 Configure applications
/thelib/src/configuration/module.cpp:177 Application admin instantiated
/thelib/src/configuration/module.cpp:177 Application appselector instantiated
/thelib/src/configuration/module.cpp:177 Application flvplayback instantiated
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 12->13 IOHT_TIMER
/thelib/src/configuration/module.cpp:177 Application proxypublish instantiated
/thelib/src/netio/epoll/iohandlermanager.cpp:120 Handlers count changed: 13->14 IOHT_TIMER
/thelib/src/configuration/module.cpp:177 Application samplefactory instantiated
/thelib/src/configuration/module.cpp:177 Application stresstest instantiated
/thelib/src/configuration/module.cpp:177 Application vptests instantiated
/crtmpserver/src/crtmpserver.cpp:264 Install the quit signal
/crtmpserver/src/crtmpserver.cpp:275 
+-----------------------------------------------------------------------------+
|                                                                     Services|
+---+---------------+-----+-------------------------+-------------------------+
| c |      ip       | port|   protocol stack name   |     application name    |
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 1112|           inboundJsonCli|                    admin|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 1935|              inboundRtmp|              appselector|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8081|             inboundRtmps|              appselector|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8080|             inboundRtmpt|              appselector|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 6666|           inboundLiveFlv|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 9999|             inboundTcpTs|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|udp|        0.0.0.0|10000|             inboundUdpTs|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0|  554|              inboundRtsp|              flvplayback|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 6665|           inboundLiveFlv|             proxypublish|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8989|         httpEchoProtocol|            samplefactory|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 8988|             echoProtocol|            samplefactory|
+---+---------------+-----+-------------------------+-------------------------+
|tcp|        0.0.0.0| 1111|    inboundHttpXmlVariant|                  vptests|
+---+---------------+-----+-------------------------+-------------------------+
/crtmpserver/src/crtmpserver.cpp:276 GO! GO! GO! (2368)

So far so good……the server is up and running now. You can stop it using Ctrl-C. Lets continue…….

2) C920 install and config (v4l2), ffmpeg installation, boneCV installation from Derek Molloy’s site

Logitec C920 is a really nice camera. Bit on the expensive side, but incredibly capable as we’ll see. I came across a post from Derek Molloy where he talks about UDP streaming h.264 streams off the C920 using a beagle board. That’s when I discovered the magic of this little camera. You see, the camera can provide image data via usb just like any other camera, but it also has the built in capability of producing a 3.5 Mb/s CBR video stream encoded in h.264 in either 640×480, 1280×720 or 1920×1080. I literally jumped out of my seat when I read this and picked one up from the local Best Buy (about $100). So now to get this signal in we need some of the tools that come with v4l (video4linux) utility package. Here is how you go about it:

  • First we need to install v4l-utils, ffmpeg and git (need git to grab the code in next step)
    apt-get install v4l-utils ffmpeg git
  • Then we need to pull down some code Derek has modified (and or written) from his git repo
    cd /opt
    git clone git://github.com/derekmolloy/boneCV
    
  • Next we need to get into the boneCV directory and recompile Derek’s capture.c program
    cd /opt/boneCV
    gcc -o capture capture.c
  • Now that we have the fresh capture program maybe we should stop and let me explain. capture.c is a V4L2 video capture example, modified by Derek Molloy for the Logitech C920 camera. He’s added the -F mode for H264 capture and associated help detail, plus an option to allow capture to capture infinite number of frames. Before we continue to the next step it’s worth trying to visualize the chain we’re trying to create. Capture (capture.c) will be called to put the camera in -F mode (1080p h.264 pre-encoded 3.5Mb/s CBR stream over USB) and to continuously pass the frames to a pipe which will feed avconv (a program that comes with ffmpeg) that will not touch the video encoding of the file but will transmit it to a RTSP destination (our crtmp streaming server). Once the stream is runnning we will use JWplayer to view the RTMP stream. The reason I decided to use JWplayer is that various incarnations of VLC say they support RTMP, but their implementation is really bad. For the longest time while using VLC to view the stream (I think it was version 2.1.x and 2.2.x nightly builds) I had freezes and breakups in the stream and I thought the poor Pi was not doing it’s job. NO, it was the player, the Pi (and Beagle Board Black) worked wonderfully. So now we need to modify the streamVideoRTSP file Derek has to look like the following (might want to save the original as .bak or something).
    #!/bin/bash
    echo "Video Streaming for the Beaglebone - derekmolloy.ie"
    echo "Piping the output of capture to avconv"
    #1080P mode 
    v4l2-ctl --set-fmt-video=width=1920,height=1080,pixelformat=1
    #720P mode
    #v4l2-ctl --set-fmt-video=width=1280,height=720,pixelformat=1
    
    # Pipe the output of capture into avconv/ffmpeg
    # capture "-F"   My H264 passthrough mode
    #         "-o"   Output the video (to be passed to avconv via pipe)
    #         "-c0"  Capture 0 frames, which means infinite frames in my program
    # avconv "-i -"  Take the input from the pipe
    #        "-vcodec copy" Do not transcode the video
    
    #1080P mode
    ./capture -F -o -c0|avconv -re -i - -f alsa -ac 2 -i hw:1,0 -strict experimental -threads 0 -acodec aac -ab 64k -ac 2 -vcodec copy -f  rtsp -metadata title=teststream rtsp://127.0.01:554/live
    #720P mode
    #./capture -f -o -c0|avconv -re -i - -f alsa -ac 2 -i hw:1,0 -strict experimental -threads 0 -acodec aac -ab 64k -ac 2 -vcodec copy -f  rtsp -metadata title=teststream rtsp://127.0.01:554/live
     

3) Configuring ddclient for dynamic DNS (optional)

This is totally optional and has no effect on the final product (makes life a bit simpler). I’m just going to provide the bare minimum explanation and my config. This process is very dependant on your DNS provider (if you have one), my example config is for my provider easydns.com. Your mileage will vary :-).

  • First we need to get ddclient program installed (this is one of dynamic dns tools available in linux)
    apt-get install ddclient
  • Then we need to edit the config file located in /etc called ddclient.conf. Here is mine which is specific for easydns.com. YOU WILL HAVE TO MODIFY THIS TO SUITE YOUR DNS PROVIDER.
    
    # Configuration file for ddclient generated by debconf
    #
    # /etc/ddclient.conf
    # updates internet ip on wired
    protocol=easydns,
    # Use this is you want to register the interface ip address (ie: You're not behind a NAT or you don't care)
    use=if, if=eth0,
    # Use this is you want to register your external ip address (ie: You're behind a NAT and want to register your outside IP address not the internal 192.168.x.x one)
    #use=web, web=checkip.dyndns.com/, web-skip='IP Address' 
    server=members.easydns.com,
    login=easydnsuserid,
    password='easydnspassword',
    hostname.domain.com
    
  • If you’ve enabled two factor authentication on easyDNS (or maybe even if you have not) there is a token that you’ll need to get called “Dynamic Authentication Token”. You can grab yours under the dynamic records page by enabling “Dynamic Authentication Token” and vieing your code. I will use XXXXXXXXXXXXXXXX as my code in the following example (NOTE: server and password clauses need to be changed):
    
    # Configuration file for ddclient generated by debconf
    #
    # /etc/ddclient.conf
    # updates internet ip on wired
    protocol=easydns,
    # Use this is you want to register the interface ip address (ie: You're not behind a NAT or you don't care)
    use=if, if=eth0,
    # Use this is you want to register your external ip address (ie: You're behind a NAT and want to register your outside IP address not the internal 192.168.x.x one)
    #use=web, web=checkip.dyndns.com/, web-skip='IP Address' 
    server=api.cp.easydns.com,
    login=easydnsuserid,
    password='XXXXXXXXXXXXXXXX',
    hostname.domain.com
    
  • Once the config is there we can restart the ddclient service
    service ddclient restart
  • If you want to check/test/debug your ddclient config, first stop the daemon that’s running in the backgroud, start it from command line in forground like below
    service ddclient stop
    ddclient -daemon=0 -debug -verbose -noquiet

4) Putting it all together and creating a webpage with embedded JWplayer to view the stream

So now you need to grab JWplayer (the free version) install it (copy the jwplayer folder) into a folder on your webserver (I copied mine into a folder of my blog server). The main file here is the HTML file that has the specifications for the stream in it. You need to create this to suite your need (ie: if you have dynamic DNS use the DNS name or if you don’t use the IP address of the Pi/BeagleBoard. Your mileage will vary :-).

Screen Shot 2013-11-09 at 4.42.17 PM

The above code is an example you will need to sustitute your own data to get it to work. We need two ssh windows off the Pi (one to run the crtmpserver and the other to start capturing and feeding it via streamVideoRTSP script. So go ahead start crtmp (see above….we did this as a test in step 1) and in the other window start streamVideoRTSP script. Those two windows should look like this:

Screen Shot 2013-11-09 at 4.59.39 PM

That’s pretty much it. If you now load the html file for jwplayer and press play (assuming you’ve done everything correctly) the stream should start playing in about 4-5 seconds. The encoding delay in the entire chain is about 2-3 seconds, the quality (considering it’s a webcam feeding a $35 computer) is really good and given proper power the Pi can steam this 1080p/30 stream without a issue. Just for the fun of it I also (at the same time) tried to feed the crtmp server (on the pi) a seperate quarter rez HD stream (640×360) encoded by ffmpeg on my desktop and yep, no problems (although the Pi is on medium overclocking settings). These RTMP streams can also be very easily scaled by passing them to larger crtmp installations and/or ustream/wowza for rebroadcast. Below you’ll find a bunch of ffmpeg command line entries I used for this second stream and also a quick (optional) write up on how I got the wireless dongle from Trendnet to work and configured from CLI.

./ffmpeg -re -i /Volumes/Qmultimedia/1217209\(73\).avi -vcodec libx264  -b 500000 -s 640x360 -strict experimental -g 25 -me_method zero -acodec aac -ab 96000 -ar 48000 -ac 2 -vbsf h264_mp4toannexb -f mpegts -metadata title=xxx udp://192.168.1.69:10000?pkt_size=1316
./ffmpeg -re -i /Volumes/Qmultimedia/1217209\(73\).avi -vcodec libx264  -b 500000 -s 640x360 -strict experimental -g 25 -me_method zero -acodec aac -ab 96000 -ar 48000 -ac 2 -f flv rtmp://192.168.1.69:1935/live/xxx
./ffmpeg -re -i /Volumes/Qmultimedia/1217209\(73\).avi -vcodec libx264  -b 500000 -s 640x360 -strict experimental -g 25 -me_method zero -acodec aac -ab 96000 -ar 48000 -ac 2 -f rtsp -metadata title=xxx rtsp://192.168.1.69:554/live

For wireless I’m using a TrendNet TEW-645UB which is directly supported under linux. Initially I used wpa_cli to get things configured and once the system was configured I massaged the files a bit. Here is a log of the whole thing:

root@picrtmp:~# lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 004: ID 157e:3013 TRENDnet 
Bus 001 Device 006: ID 046d:082d Logitech, Inc. 
root@picrtmp:~# wpa_cli 
wpa_cli v1.0
Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> and contributors

This program is free software. You can distribute it and/or modify it
under the terms of the GNU General Public License version 2.

Alternatively, this software may be distributed under the terms of the
BSD license. See README and COPYING for more details.

Selected interface 'wlan0'

Interactive mode

> scan
OK
CTRL-EVENT-SCAN-RESULTS 
> scan_results
bssid / frequency / signal level / flags / ssid
7c:d1:c3:zz:yy:xx	2411	-50	[WPA2-PSK-CCMP][ESS]	Nerdlogger
7c:d1:c3:zz:yy:xx	2412	-51	[WPA2-PSK-CCMP][ESS]	MaNiAc 2Ghz
8c:7c:b5:zz:yy:xx	2437	-64	[WPA-PSK-CCMP][ESS]	PS3-3313551
> add_network
0
> set_network 0 ssid "Nerdlogger"
OK
> set_network 0 psk "supersecretpassword"
OK
> enable_network 0
OK
> add_network
1
> set_network 1 ssid "MaNiAc 2Ghz"
OK
> set_network 1 psk "supersecretpassword"
OK
> enable_network 1
OK
> save_config
OK
> quit
> 
root@picrtmp:~# iwconfig
wlan0     IEEE 802.11bgn  ESSID:"MaNiAc 2Ghz"  
          Mode:Managed  Frequency:2.412 GHz  Access Point: 7C:D1:C3:CA:0F:7A   
          Bit Rate=43.3 Mb/s   Tx-Power=20 dBm   
          Retry  long limit:7   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:on
          Link Quality=59/70  Signal level=-51 dBm  
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:1   Missed beacon:0

lo        no wireless extensions.

eth0      no wireless extensions.

root@picrtmp:~# ifconfig
eth0      Link encap:Ethernet  HWaddr b8:27:eb:37:a6:b3  
          inet addr:192.168.1.189  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:10397 errors:0 dropped:1 overruns:0 frame:0
          TX packets:5361 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:726543 (709.5 KiB)  TX bytes:918179 (896.6 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

wlan0     Link encap:Ethernet  HWaddr 00:14:d1:cc:16:d2  
          inet addr:192.168.1.69  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1389 errors:0 dropped:41 overruns:0 frame:0
          TX packets:36 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:466517 (455.5 KiB)  TX bytes:4773 (4.6 KiB)

root@picrtmp:~# cat /etc/network/interfaces 
auto lo

iface lo inet loopback
auto eth0
iface eth0 inet dhcp

auto wlan0
allow-hotplug wlan0
iface wlan0 inet manual
	wpa-driver wext
	wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf

iface default inet dhcp

iface work inet dhcp

iface home inet static
	address 192.168.1.69
	netmask 255.255.255.0
	network 192.168.1.0
	broadcast 192.168.1.255
	gateway 192.168.1.1
	dns-nameservers 192.168.1.1

root@picrtmp:~# cat /etc/wpa_supplicant/wpa_supplicant.conf 
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
	ssid="Nerdlogger"
	psk="supersecretpassword"
	id_str="work"
}

network={
	ssid="MaNiAc 2Ghz"
	psk="supersecretpassword"
	id_str="home"
}

root@picrtmp:~# 

After battling this for about a week I think I’ve got it figured out. You can install all the required packages and get everything to talk to your license server from command line. BTW, before I start, you need to have a functional license server otherwise you can stop reading now. I’m gonna use licserver.com as the domain name of mine, so substitute your DNS name where necessary. Before we start you need to figure out your product codes from the table at the following address:

http://usa.autodesk.com/adsk/servlet/ps/dl/item?siteID=123112&id=21481916&linkID=12305695

My products are Maya (657F1), Mudbox (498F1) and my Suite number for ECSU is 793F1. You’ll need these later. Also my base directory (current directory) in these commands is “MacOSX”, there are separate folders for the individual ECSU apps under this folder. First we install Maya:

installer -verbose -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Maya2014.mpkg -target /

Then we create a file named Maya2014.lic in folder /private/var/flexlm and put the following text inside it:

SERVER licserver.com 0 
USE_SERVER

Make sure this file has at least read permission for group and others (mine is 744). Then we create another file named License.env in folder /Applications/Autodesk/maya2014/ and put the following text inside it:

MAYA_LICENSE=unlimited 
MAYA_LICENSE_METHOD=network

Install the standalone adlmgr package (you’ll get errors later if you don’t do this):

installer -pkg ./MacOSX/Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/AdLM_standalone.mpkg -target /

Now comes the fun part of enrolling the serial number into the license manager. Remember the Product code and the Suite code I had you look up earlier, we need them now. In the following command line -i inserts, “N” is for network license type, First Code is the Product code (Maya) and the second code is the Suite code (ECSU in my case). The following command should get the license added (use the proper serial# starting with 379):

adlmreg -i N 657F1 793F1 2014.0.0.F 379-XXXXXXXX /Library/Application\ Support/Autodesk/Adlm/PIT/2014/MayaConfig.pit

If you screw up you can remove the license via this command:

adlmreg -u N 657F1

Next step is optional. When Maya starts it displays a bunch of intro screens. Since my deployment is run by a KACE appliance I need to be able to Pre-disable these popup screens. The following command will let you do that:

/usr/bin/defaults write /Library/Preferences/com.autodesk.MC3Framework MC3Enabled -int 0

Next we need to install all the Optional installs Maya comes with. Some of it is probably already installed by the Maya installer, but I installed them again for good measure. No harm done. Use the following 11 installer commands to install them:

installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/ADC_docs8.0.pkg -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/AutodeskBackburner2014.mpkg -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/AutodeskDirectConnect8.0.pkg/ -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/Composite2014.pkg -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/MatchMover2014.pkg -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/Maya_quicktime_components.pkg -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/autodesk.backburner.monitor-2014.0_439_i386.pkg -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/autodesk.dlcommon.libraries_2014.2-2043.i386.pkg -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/autodesk.webentry-1.0-603.i386.pkg -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/backburner-2014.0_1635_i386.pkg -target /
installer -verboseR -pkg ./Maya/Install\ Maya\ 2014.app/Contents/Resources/Maya/Additional\ Items/mentalrayForMaya2014.0.pkg -target /

Now check to make sure Maya is working and all the other extra little apps we installed are functional. They should be. If not stop and review. Assuming it’s all working, lets move on and install Mudbox and the last few optional installs. First we need to install Mudbox:

installer -verboseR -pkg ./Mudbox/Install\ Mudbox\ 2014.app/Contents/Resources/Mudbox/Mudbox2014.mpkg/ -target /

Then we need to create the License.env file in /Applications/Autodesk/Mudbox2014/ folder with the following content:

MUDBOX_LICENSE=unlimited 
MUDBOX_LICENSE_METHOD=network

Now comes the fun part of enrolling the serial number into the license manager. Remember the Product code and the Suite code I had you look up earlier, we need them now. In the following command line -i inserts, “N” is for network license type, First Code is the Product code (Mudbox) and the second code is the Suite code (ECSU in my case). The following command should get the license added (use the proper serial# starting with 379):

adlmreg -i N 498F1 793F1 2014.0.0.F 379-XXXXXXXX /Library/Application\ Support/Autodesk/Adlm/PIT/2014/MudboxConfig.pit

If you screw up you can remove the license via this command:

adlmreg -u N 498F1

Only two more install command left to go. These are optional packages that are part of ECSU. Use the following two installer commands to get them installed:

installer -verboseR -pkg ./mentalraySatellite/Install\ mentalraysatellite\ 3.11.1.app/Contents/Resources/mrsat/mrsat3.11.1.mpkg -target /
installer -verboseR -pkg ./SuiteExclusives/Install\ Suite\ Exclusives\ 2014.app/Contents/Resources/Turtle/MayaTurtlePlugIn2014.0.pkg/ -target /

Now you should be able to run Mudbox and pretty much all the other apps that are in Autodesk folder under Applications. Hopefully it all worked out for you. I will try to get a KACE workflow done for this in the next few days. If you’re a KACE user and end up making the workflow before I do, please share :-).

Le Mystère du printemps

datePosted on 16:06, June 30th, 2013 by Many Ayromlou
IMG_0845DSC01629DSC01637DSC01646DSC01650GOPR0010
GOPR0018IMG_0841IMG_0858IMG_0864IMG_0866IMG_0868
IMG_0871IMG_0876IMG_0877IMG_0878IMG_0881IMG_0886
IMG_0892IMG_0893IMG_0901IMG_0907IMG_0908IMG_0910

Le Mystère du printemps, a set on Flickr.

TSG Sports Bike Shoot

datePosted on 17:05, May 5th, 2013 by Many Ayromlou

I know this is almost a year old, but I just noticed that it was not posted.

Model Shoot with Toronto Camera Club

datePosted on 16:58, May 5th, 2013 by Many Ayromlou

Recently shot with a bunch of people from Toronto Camera Club at their location. It was a great shoot, great models and MUA’s and a bunch of fun photographers. Just finished the sets and uploaded them to flickr. Here is a quick slideshow:

NAB2013 Recap….

datePosted on 12:03, April 14th, 2013 by Many Ayromlou
NAB2013
  • DAY 1 (South Hall Upper Floor):
    • Screen Shot 2013 04 13 at 5 23 28 PM
  • Capella:
    • Carina 1 frame latency DMA (Direct Memory Access) Camera and Video processing card
    • Cambria Live Series software
  • NTT Electronics:
    • Realtime H.264/AVC HD codec with 60p and 33 msec latency
    • AVC/H.264 Codec for Contribution and Distribution with 1 frame latency and 16ch/8 PES audio
    • Ultra Low Latency H.264 software Codec using Capella Carina 1 frame latency DMA (Direct Memory Access) Camera and Video processing card
  • Elemental:
    • HEVC H.265 software/hardware decoder
    • 4K Encoding for On Demand and Real-time Delivery
  • Sonic Notify
  • Nimbus (http://www.nimbus.kr):
    • Full HD 1080p60 Zero delay (10ms) H.264 Encoder for remote desktop
  • Panopto Video Platform: vCMS with E-learning recorder
  • Angry Moose :-)
  • VanguardVideo:
    • V.265 – World’s first pure software H.265/HEVC real-time encoder
    • H.265/HEVC 4K UltraHD Encode/Decode
  • Epson Curved Edgeblending Projection:
    • Concave or Convex multi projector curved edgeblending
    • HDBaseT based projectors PowerLite Pro G6900WU
    • HDBaseT based projectors PowerLite Pro G6900WUHDBaseT based projectors PowerLite Pro G6900WU
    • BrightLink Pro 1410Wi instant Whiteboard solution (no PC required)
  • Middle Atlantic
    • Presentation/Video Conferencing Monitor Pedestal
    • Screen Shot 2013 04 13 at 4 42 47 PM
    • Rack Link Intelligent Power Management
    • Screen Shot 2013 04 13 at 4 46 59 PM
    • New additions to ViewPoint Line of operator consoles
  • Brightcove Video Cloud:
    • Cloud based online video platform (vCMS)
    • Screen Shot 2013 04 13 at 4 58 27 PM
  • Streamstar streaming Innovations:
    • Webcast appliance with instant replay function
  • LiveU
    • Portable Uplink Solution
    • iPhone Uplink Solution with MiFi stick
  • Toshiba
    • On-Air Max Flash – Flash Memory playout server
    • ExaEdge – World’s first SSD-to-IP Direct Streaming Server w/ 64K concurrent sessions
  • DAY 2 (South Hall Lower Floor):
    • Screen Shot 2013 04 13 at 5 21 47 PM
  • Black Magic:
    • Black Magic
    • Pocket Cinema ($995)
    • Cinema Camera ($2995)
    • Production 4K ($3995)
    • BMCC Rigs
    • BMCC4K Rigs
  • RED labs
  • Christie:
    • World’s first 4K 60Hz DLP Projector
  • AJA:
    • Hi5-4K – 4K SDI to 4K HDMI converter
    • Screen Shot 2013 04 13 at 5 40 31 PM
    • T-Tap – HD-SDI to Thunderbolt converter
    • Screen Shot 2013 04 13 at 5 43 14 PM
  • MATROX
    • Avio KVM Extenders – Dual DVI Fiber KVM Extender up to 4Km/2.5mi (Zero Compression, Zero Latency)
    • Screen Shot 2013 04 13 at 5 51 40 PM
    • Maevex Video Over IP Digital Signage solution
    • Screen Shot 2013 04 13 at 5 47 50 PM
    • Matrox Mojito 4K editing solution
    • Screen Shot 2013 04 13 at 5 55 48 PM
    • Matrox MicroQuad – Quad SDI to HDMI multiviewer for 3G/HD/SD
    • Screen Shot 2013 04 13 at 5 58 56 PM
  • Ventuz
    • Real-time graphics content creation for professional presentations, video wall setups, multitouch applications or broadcast graphics
    • Spotted Zebra Ltd
    • MultiTaction Cell Displays – unlimited touch points, including hands, fingers, fingertips, 2D markers, real-life objects 
    • 3Monkeys
  • Haivision
    • Viper
  • Darim
    • Microstation and standLED lights
  • CalDigit
    • VR mini 2
    • Thunderbolt Station
  • Promise Technology
    • FiberChannel to Thunderbolt Interface
    • V-Trak zero server workgroup GFS (VTrakFS) Fiberchannel Storage
    • Screen Shot 2013 04 13 at 6 37 10 PMScreen Shot 2013 04 13 at 6 40 22 PMScreen Shot 2013 04 13 at 6 40 40 PM
  • Samsung Transparent Display
  • LiveStream
  • DIT Station
    • Rogue4 on-set data management and playback workstation
  • SGI (Silicon Graphics)
  • DAY 3 (Central Hall)
  • The PadCaster
  • Portalis
    • The Pro-xi workstation integrator
  • Panasonic
    • Ultra Wide Camera Solutions
    • 4K Camcorder
  • JVC
    • GY-HM650 2.0 ProHD mobile news camera – Dual coded with wifi and optional LTE modem for realtime streaming
  • Codex – The Vault digital recorder
  • DJI
    • Phantom
  • Fraunhofer IIS:
    • Computational Imaging – HDR Camera/Camera Array
    • Multi-view capturing for lightfield computation, HDR and higher frame rates
    • Multi-view capturing for lightfield computation
    • HDR video capturing with a single shot
    • Multi-view capturing for lightfield computation
  • Tascam:
    • DR-60D DSLR External Audio Recorder
    • DR-60D DSLR External Audio Recorder
  • ATOMOS
    • H2S HDMI to HD-SDI (or vice versa)
    • Samurai Blade
  • Freefly
    • Movi M10
  • Teradeck
    • VidiU portable RTMP streamer
  • Syrp genie motion controller for time lapse photography
  • Sony 4K Stitch with Virtual Camera
  • DAY 4 (North Hall)
  • IBM
    • PureData System for Analytics
    • GOPR0247
  • NHK
    • Over-the-Air Transmission of Super Hi-Vision (8K)
    • Super Hi-Vision Camera’s
    • Hybrid Cast – Accurate Graphic Rendering synchronized with frame and second screen

This took a while to figure out, mainly because I’m a unix guy trying to “figure out” Windows Server and it’s archaic ACL system and the fact that ACL’s/attributes under OSX are just insane. The main issue I had with all the other recipes on the net describing this process was that it did NOT work for OSX/Finder. When users transferred the files, Finder was not able to strip off it’s “in-use” attribute from the file once copied to the destination. This would leave files in limbo (greyed out) and no one could touch/access them from another Mac until I stripped the “in-use” attribute off manually. Normally SMB capable NAS’s ignore Finder/OSX attributes and this does not happen, but FS7500 is “mac friendly” and preserves the attributes so we had to figure out a way to give Finder enough rights to be able to strip the attribute off once the file was copied.

The core idea here is that you have a windows share (\\elm\DROPBOX in my case) which has a bunch of subfolders under it, one per class (they are in the form of BDCxxx.yyy in my case). What we’re trying to do is give AD users who are in AD groups (also called BDCxxx.yyy in my case) which represent classes enough permission to get inside \\elm\dropbox and see the name of the subfolders and be able to drag files onto the appropriate class subfolder (BDCxxx.yyy), essentially submitting their assignment. What we don’t want to let the users do is to peak inside those subfolders. It’s the equivalent of a “write only” group permission on a folder (no execute or read bit) in unix land. We also want to have our instructors be able to access everything in the DROPBOX share, so we use a group called DropBoxMasters for that purpose.

For the sake of this example I will use the student/class group BDC974.011 which the students belong to and DropBoxMasters group for our instructors. So here we go:

1) We obviously need a share. If you’re using a FS7500 NAS you just create the share and that’s it, no sharing permissions, everything is controlled by Windows ACL’s. If your share is on windows then I guess you can give full control sharing permissions to Domain Users. Once this is done we access \\elm to set the Windows permissions on DROPBOX share.

2) For DROPBOX we need the following permissions to be set to Allow and Apply it to “This folder only”: Traverse folder/execute file, List folder/read data, Read attributes, Read extended attributes, Read permissions. This will allow our BDC974.011 students to see the content of this folder (i.e. the subfolders, one per course). Remember that you need to create this permission set for each individual course/group/class. And remember to apply to “This folder only”.

Screen Shot 2013-02-28 at 3.11.57 PM Screen Shot 2013-02-28 at 3.12.15 PM

3) Still on DROPBOX share permissions we want to setup the DropBoxMasters group. This one is easy since it’s “Full control” permission that applies to “This folder, subfolder and files”. Easy :-)

Screen Shot 2013-02-28 at 3.16.58 PM

4) Before we go on, a note about the above process. In the permissions/Advanced security settings you should only have the “class/course” groups, the DropBoxMasters group, SYSTEM group (with full control) and Domain Admins (with full control). Next we want to create the subfolders inside DROPBOX, one subfolder per course/class (BDC974.011 in my case). Permission wise we want to setup the following permissions for the group that matches our course/folder (i.e. the example screen shots here are for group BDC974.011 on subfolder \\elm\DROPBOX\BDC974.011). We need the following permissions to be set to Allow and Apply it to “This folder only”: List folder/read data, Read attributes, Read extended attributes, Create files/write data, Create folders/append data, Write attributes, Write extended attributes, Read permissions.

Screen Shot 2013-02-28 at 3.31.53 PM Screen Shot 2013-02-28 at 3.32.07 PM

5) Still in the security settings for the course subfolder we need to add “CREATOR OWNER” to the list of permissions (This is a built-in windows entity) and give it the following permissions for “Files only”: basically all the allow check boxes EXCEPT the following (leave unchecked)……Full control, Change permissions, Take ownership. Remember these permissions are to be applied to “Files only”.

Screen Shot 2013-02-28 at 3.37.06 PM Screen Shot 2013-02-28 at 3.37.18 PM

That’s it…..Now just keep repeating this for all your courses/groups.

Get rid of double (triple) entries in Finder’s “Open With” Menu

datePosted on 09:55, February 20th, 2013 by Many Ayromlou

Does sh*t like this make you wanna smack your mac :-)

Screen Shot 2013-02-20 at 9.48.59 AM

Here is a quick way to rebuild the Launch Services database and get rid of duplicates in the Open With submenu:

/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user

This process should take about a minute or two. You should check to see if this has fixed the problem. On my machine, running 10.8.2, I had to also restart Finder to complete the process using the following command:

killall Finder

That’s all…..Now Open With submenu is squicky clean

Screen Shot 2013-02-20 at 10.07.02 AM

Setting NTP time server on Dell FS7500 through command line

datePosted on 10:40, January 23rd, 2013 by Many Ayromlou
  • SSH to the Group Interface IP (10.100 in our case)
  • Login as “fse”
  • Password “”
  • At the CLI prompt check the current cluster time using
    system time-configuration view
  • If the time is wrong reset it (This will turn off NTP sync) using
    system time-configuration -updatetime "DD/MM/YYYY HH:MM:SS"
  • Use the view command to check it again.
  • If you need to set the NTP time use your DC’s NTP functionality on the client network and set it using
    system time-configuration set-ntpserver xxx.xxx.xxx.xxx

That’s it for now…….

Renew a DHCP lease

datePosted on 12:46, January 3rd, 2013 by Many Ayromlou

Renew a DHCP lease:

Renewing a DHCP lease via the Network System Preference Pane has the advantage of not dropping the connection, unlike switching the interface to BOOTP and back to DHCP. This command mimics that behavior. 

(Via MacOSXHints.com)

123... 636465PreviousNext