Remote presentation screencasts with YouTube recordings for meetups in Google Hangout

After seeing it in happening in a HelsinkiJS, I figured out that having a remote presenter in your local meetup kicks ass. Thanks Oleg for getting our meta meetup together for sharing the best practices!

Why a remote presenter via screencast?

  • Remote presenters offer some more color over seeing the same old faces in your meetup all the time
  • More information trade across organizational borders… or countries.
  • The benefits of the online presentation are not limited for the local participants – anyone can join to see the online presentation online – like all those home daddies who often miss the chance to be there in person.

1. Meet Google Hangout

Google offers Hangout video sharing feature in their Google+ social service. The benefits of doing a screencast presentation in Google Hangout include

  • Anyone can watch the live stream
    • The number of participants is not limited or pre-selectd like e.g. in Skype.
    • You get anonymous Youtube short URL where anyone can follow live broadcast
  • You get automatically YouTube video recording out of your broadcast. This is a big plus as post-processing recordings from the conferences have always been great pain.
  • Google Hangout works on any OS, maybe even on some mobile devices?
  • Google is generously offering the bandwidth from their streaming CDN network. You don’t need to provide the bandwidth for those 100 viewers of 2 mbit stream 🙂

2. Do the math

  • In local meetup you reach the 30 people in the room
  • With live Google Hangout you can reach 100 or so people if you advertise the event beforehand in your community medias
  • With YouTube recording you can reach all those 5000+ people who were not there in time or space when it happened

… this is not good only for the local community, but also good in general to have high quality recordings of your presentation to share later on for anyone.

3. The disadvantages of Google Hangout

  • You need a Google+ account for sharing your webcam or screen (your soul, real name, I know…)
  • The hangout organizer must be able to bind his/her Google+ account to YouTube account with real name policy permanently
  • … Google is little shortsighted here: you may need to create fake non-person G+ credentials for meetup organizations (now I hear Eric Schmidt crying)

Image

 

4. Using Hangout with Google Apps user account

If your organization is using Google Apps for email you may be able to enable both YouTube and G+ in your domain settings. After this, there still exist real name policy problems and you cannot use a name like “Secretary of Python Finland” in G+. So better come up with a foreign fake name… Also settings the name in G+ will silently enforce this name on Gmail and other Google services, so be careful.

Another warning: YouTube cannot be enabled for Google Apps accounts in all countries, so check this beforehand before trying to create an organizational G+ account. Finland was such a country. Rogue Gmail account, here I come…

Image

5. Preparing for live Google Hangout broadcasting

Start preparing a day before the event! As you can see the account policy and such may lie down obstacles on your way to become a screencast ninja. As sad it is, you need to practice the technical aspects of Hangout thing to make sure it works when the great day comes.

The encoding of live video will max out at least one of your CPU cores. Make sure you have powerful enough hardware under your fingers when you share your screen.

First your Google identities and cookies will become messed up in your web browser if you try to use G+ and/or Youtube with several Google accounts at once. In theory Google has some clever cookie tossing to tackle this problem, but in practice it just doesn’t work. Use Multifox Firefox extension and open a new identity window where the only logged in Google user is your Hangout user.

Image

Make sure all your presenters have their G+ account created beforehand and you have added them on your friend list. Make sure that the presenters have test drived the screensharing on their personal laptops – it would be shameful if streaming would fail because of something like a Linux driver bug. You will need to install a browser plug-in for the video encoding: I know at least Google Chrome and Firefox work, but I don’t suspect other major desktop browsers should have any problems (Lynx, Iceweasel and others, sorry again…)

To test things out, ask people to come to a test Hangout session where you really see their screensharing is working with you and you learn how to use Cameraman feature (more below).

6. Creating your Hangout

Just login to Google, click G+ and then Hangout > Create hangout.

A new pop-up window ensures. You need to also accept some additional site policy and Google warns you that you must have permission to broadcast and record the material. Make sure you obtain necessary permission from the presenters beforehand.

Image

Image

7. Starting the screencast

Hangout offers options to stream your webcam, screencast any of your monitors or screencast a particular window. There doesn’t seem to be option for a floating head on the top of presentation yet.

Image

 

8. On Air

(oblig. related Reckless Love music video)

The broadcasting can be public or private (only for invited hangout participants). The latter doesn’t scale well when you try to make it as pain free as possible for others to see the presentation online.

When you go public “on air” you’ll receive the YouTube short URL which has live broadcasting as Flash video widget (no HTML5 or WebRTC yet, sorry!). No YouTube login is needed in order to see the video in this URL: you can share it in IRC, Twitter and other social networks for your audience.

Image

Image

As the summoner of the Hangout, you have a Cameraman feature which controls who of the participants “is live” in the main live stream. You can switch the stream between any of the presenters and your local webcam, just for the audience to say hi for the presenters.

Image

Image You have a group chat feature  in Hangout. But often the chat is best to handle offband, like in IRC, where your target audience naturally come together online and you have better moderation tools in your possession.

Image

Please note that public broadcasting may attract unwanted attention. My fellow friends in Bitcoin Hackathlon got flooded over by kids when they were experimenting with Hangout. You can directly share your Hangout URL from the web browser’s address bar, but it means that anyone using that URL can join in Hangout for chat and video streaming.

9. Ending the Hangout and video postprocessing

After you press “terminate the call” icon in the top right corner, you’ll get a message telling that the recording of the live stream will be uploaded to YouTube.

Image

You can edit the recording later on in YouTube.

10. Bonus photo

I found a lovely Google Effects panel in Hangout. You can play sounds (drums, applause) or glue artifacts on the top of live video stream. It’s Movember and I seem to be victorious.

Image

 

\"\" Subscribe to RSS feed Image Follow me on Twitter Image Follow me on Facebook Image Follow me Google+

BitReader – Python module for reading bits from bytes

I worked on a project that involved working with MPEG Transport Stream and Digi-TV(DVB). EPGReader to be exact.

The MPEG TS is a binary format, where multiple fields can be defined within a single byte. I could not use Python’s struct module because it only works with bytes or larger and the fields I had were just a couple of bits. First I started with regular bitshifts and bitmasks, but I soon realised it was very error prone task for me. It was very easy to make mistakes and the code was not very readable either.

For example, first 3 bytes of MPEG TS header contains a SYNC_BYTE, which is 1 byte in size and always has the value 0x47. This byte is used to detect packets from the stream. Each packet is 188 bytes long. The next bit is “transport error indicator”, which is set by receiver hardware to flag errors in demulation( analog signal to bits ), next bit is “payload unit start indicator” indicating that the current packet starts a new payload of data, then comes “transport priority” bit and finally “packet id”. Normally I’d write code something like following:

data      = read(3)          # Get 3 bytes of data
sync_byte = data >> 16       # Get bits 24-16
tei       = data >> 15 & 0x1 # 16. bit
payl_start= data >> 14 & 0x1 # 15. bit
tp        = data >> 13 & 0x1 # 14. bit
pid       = data & 0x1FFF    # Get last 13 bits

On top of that I needed to store the values in dictionary. As you can see this is not very readable nor convenient. So I figured there must be something easier.

1. Meet BitReader

spec = (
    # Name of the data to read
    'sync_byte',
    # How many bits to read( 8 bits = 1 byte )
    8,
    'tei',
    1,
    'payl_start',
    1,
    'tp',
    1,
    'pid',
    13
)

reader = BitReader(spec)
data   = reader.read(read(3))
assert data.sync_byte == 0x47

And if and when one needed to add one more byte and couple of variables, that’s when the code starts to break with bitshifts. Any change to the original data size requires you to change the bitshifts accordingly. Also adding new values to the middle requires changes to bitshifts, in case you missed it in the spec the first time etc.

data      = read(4)          # Get 4 bytes of data
sync_byte = data >> 24       # Get bits 32-24
tei       = data >> 23 & 0x1 # 24. bit
etc... not very interested on getting this right, but you'll get the idea

When using BitReader, I just give the variable name and how many bits it takes. Simple as that. No need to touch the other variables.

spec = (
    # Name of the data to read
    'sync_byte',
    # How many bits to read
    8,
    'tei',
    1,
    'payl_start',
    1,
    'tp',
    1,
    'pid',
    13,
    'scrambling',
    2,
    'has_adapt',
    1
    'has_payload',
    1,
    'continuity',
    4
)

reader = BitReader( spec )
data   = reader.read(read(4))

And it doesn’t matter if the new values are added to the beginning, middle or at the end.

2. About performance & syntax

BitReader is a bit slower than using bitshifts, but it was still easily fast enough for the task I worked on. And if compiled using Cython the performance nearly doubles without any code change.

Is it faster? – Performance, no, but you are faster. Have a cup of C if you want speed. Is it more readable? – Yes. Makes life easier? – You bet!

Somebody might look at the specification syntax and quickly note that I could have used dictionary instead. Unfortunately it is not possible because the order is needed and dictionary does not preserve it.

And what about using 2-tuples ( variable, bits )? Is it more readable and less error prone? Not sure, maybe, but I thought I’ll save myself from typing parenthesis 🙂

The specification syntax was inspired by domgen… or the other way around. Can’t remember which came first.

You can also convert the data back into binary format. The read returns a BitData object, which implements ‘dump()’ method, which returns an array.array(‘B’) containing the bytes. You can change the attributes of the BitData and then dump the data back into array and easily write it to a file using array.tofile(f) or send it to network.

A Javascript port might be interesting for web apps… Especially mobile apps, which often have slow connections. And a hand made C module would probably be at least as fast as the bitshifts on Python.

3. Project location

Get the code from bitbucket.

domgen – Creating HTML with Javascript without DOM API

Tired of using Javascript DOM API for generating HTML dynamically? Meet domgen. domgen is a tool for easy dynamic content generation via Javascript. It generates DOM elements from dictionary specification similar to HTML and eliminates the need for cumbersome DOM Javascript API.

domgen uses a simple specification to generate the HTML. In some cases it’s more reliable to use DOM API to generate HTML instead of using innerHTML. We have had problems especially with iPhone when using innerHTML. See for example http://pastebin.com/LLk3J0iH or google “iPhone innerHTML” for more info. In fact, innerHTML is not even part of the HTML standard even though it exists on every browser.

So if you want to add dynamic HTML properly, you should use the Javascript DOM API. Consider the following short HTML where the contents inside body had to be generated:

<body>
    <div id="mydiv">my div</div>
</body>

Using Javascript DOM API:

// Get the body tag
var body = document.getElementsByTagName("body")[0];
// Create 'div' element
var mydiv = document.createElement("div");
mydiv.setAttribute("id", "mydiv");
mydiv.innerText = "my div";
// Attach the div to body
body.appendChild(mydiv);

And using domgen:

var spec = [
    'div',
    {
        id : 'mydiv',
        _innerText : 'my div'
    }
];
domgen.generate( domgen.get("body")[0], spec);
// or with jQuery
domgen.generate( $("body")[0], spec);

To me, domgen seems a lot easier to read and work with. Get code and more examples here: https://bitbucket.org/mfabrik/domgen

Open source contribution agreement template

We are looking for creating contribution agreements for few new open source projects. IANAL, but hiring a real lawyer is freaking expensive.

The thing is that we, us a company, want to guarantee that all code coming into the project is “clean”. We also want to guarantee our right to change the license in the future (GPL -> BSD, GPL -> Apache, etc.)

Thus far, the best free, as in freedom and in beer, contribution agreement template we have found is Sun Contribution Agreement 1.5 which is available under  Creative Commons Attribution-Share Alike 3.0 license. It is at least used by high profile Phonegap project (Nitobi as the company) if you don’t count OpenSolaris anymore as open source project.

IANAL, but if I understood correctly, the agreement basically says

  • the company can do whatever it wish with your contributions (joint ownership)
  • the company is entitled to release your contributions under open source license – perfect for GPL’ed projects. The exact wording is terms. Any contribution we make available under any license will also be made available under a suitable FSF (Free Software Foundation) or OSI (Open Source Initiative) approved license.

Since I couldn’t find the orignal document in editable form (PDF was the best I could get) I made OpenOffice.org ODS document out of it with easily replaceable identification information.

Comments welcome.

The agreement text pasted below.

YOURPROJECT Contributor Agreement

These terms apply to your contribution of materials to the YOURCOMPANY ("us"/"our"), and set out the intellectual property rights you grant to us in the contributed materials.  If this contribution is on behalf of a company, the term "you" will also mean the company you identify below. If you agree to be bound by these terms, fill in the information requested below and provide your signature. 

Read this agreement carefully before signing. 

1.  The term "contribution" means any source code, object code, patch, tool, sample, graphic, specification, manual, documentation, or any other material posted or submitted by you to the project. 

2.  With respect to any worldwide copyrights, or copyright applications and registrations, in your contribution: 

you assign to us joint ownership through this document, and to the extent that such assignment is or becomes invalid, ineffective or unenforceable, through this document you grant to us a perpetual, irrevocable, non-exclusive, worldwide, no-charge, royalty-free, unrestricted license to exercise all rights under those copyrights. This includes, at our option, the right to sublicense these same rights to third parties through multiple levels of sublicensees or other licensing arrangements;
you agree that each of us can do all things in relation to your contribution as if each of us were the sole owners, and if one of us makes a derivative work of your contribution, the one who makes the derivative work (or has it made) will be the sole owner of that derivative work;
you agree that you will not assert any moral rights in your contribution against us, our licensees or transferees;
you agree that we may register a copyright in your contribution and exercise all ownership rights associated with it; and
you agree that neither of us has any duty to consult with, obtain the consent of, pay, or give an accounting to the other for any use or distribution of your contribution. 

3.  With respect to any patents you own, or that you can license without payment to any third party, through this document you grant to us a perpetual, irrevocable, non-exclusive, worldwide, no-charge, royalty-free license to: 

make, have made, use, sell, offer to sell, import, and otherwise transfer your contribution in whole or in part, alone or in combination with or included in any product, work or materials arising out of the project to which your contribution was submitted, and
at our option, to sublicense these same rights to third parties through multiple levels of sublicensees or other licensing arrangements. 

4.  Except as set out above, you keep all right, title, and interest in your contribution.  The rights that you grant to us under these terms are effective on the date you first submitted a contribution to us, even if your submission took place before the date you sign these terms. Any contribution we make available under any license will also be made available under a Free Culture (as defined by http://freedomdefined.org)  or Free Software/Open Source licence (as defined and approved by the Free Software Foundation or the Open Source Initiative).

5.  With respect to your contribution, you represent that it is an original work and that you can legally grant the rights set out in these terms; 

it does not to the best of your knowledge violate any third party's copyrights, trademarks, patents, or other intellectual property rights; and
you are authorized to sign this contract on behalf of your company (if identified below). 

6.  The place of performance is the registered seat of

	YOURCOMPANYNAME
	YOURCOMPANYADDRESS1
	YOURCOMPANYADDRESS2
	YOURCOUNTRY
	YOURCOMPANYBUSINESSID	

Any disputes concerning this agreement including the issue of its valid conclusion and its pre and past contractual effects are exclusively decided by the competent court in YOURHOMECITY, YOURCOUNTRY or, at our discretion, also by the competent court is whose district you may have your residence, your registered seat, an establishment or assets.

If available, please list your YOURPROJECT username(s) for the YOURPROJECT systems.

Username(s): __________________________________________________________________

_______________________________________________________________________________

Your contact information (Please print clearly) 

Your name: ____________________________________________________________________

Your company's name (if applicable): __________________________________________

Mailing address: ______________________________________________________________

Telephone, Fax and Email: _____________________________________________________

Your signature: _______________________________________________________________

Date: _________________________________________________________________________

To complete this agreement:
email a scanned copy of a signed agreement to
fax a signed copy to + .....; or
post a signed copy to:

	YOURCOPMANYNAME
	YOURCOMPANYADDRESS1
	YOURCOMPANYADDRESS2
	YOURCOUNTRY

This agreement is based on version 1.5 of the Sun Contributor Agreement, which
can be found at:

    http://www.sun.com/software/opensource/contributor_agreement.jsp

This document is licensed under a Creative Commons Attribution-Share Alike 3.0
Unported License http://creativecommons.org/licenses/by-sa/3.0

\"\" Subscribe to RSS feed Image Follow me on Twitter Image Follow me on Facebook Image Follow me Google+