Tom Krcha's FlashRealtime

Hey amigo! These are my notes. I'm Platform Evangelist with Adobe.


Video-on-Demand over P2P in Flash Player 10.1 with Object Replication

July 28th, 2010

In the previous tutorial File Sharing over P2P in Flash Player 10.1 with Object Replication we went through the Object Replication basics. And you can see that the Receiver is requesting packets one by one. That’s not suitable for the real world app, but it’s good for testing on a LAN to see the progress. In the real world app, you can immediately request all packets using NetGroup.addWantObjects(beginIndex, endIndex);.

Transferring VoD video over P2P

Let’s get something real with Object Replication. The use-case I like most is a Realtime P2P Distributed System for Video-on-Demand.
Video-on-Demand P2P Object Replication Scheme

This is the vision. It could be nicely integrated by video/news portals, especially on the currently most demanded videos (latest hits, hot news, etc.). When users are currently acquiring one video or a few hot videos from a server, why not try to lighten the load on the server and improve the viewers experience.

I am not afraid to say that this can save you millions or at least most of your video portal costs.

*Note: This is only a study how it could work. It still needs further work and testing.

See how it works

This technique shows how you can distribute VoD video with Flash Player 10.1 Object Replication

Getting the video
To download a video file, you can use URLStream class. Register ProgressEvent to control every byte segment you get, while putting these segments together you can already start creating deliverable chunks (~64KB) for object replication. If you are on a slow network, you will probably get more segments to chunk, than on a fast network. This is illustrated below. It doesn’t matter, just keep in mind, that you need to wait until you can separate these segments into chunks.

Sharing the video
While downloading, you can already start sharing the video in the P2P network using Object Replication. Once others receive packets, they start sharing them as well, while receiving the rest. This makes the network more stable and less dependent on a relatively low number of original providers.

Viewing the video
Flash Player 10.1 added a new NetStream function called appendBytes, which enables you to pass a ByteArray containing FLV bytes to a NetStream and then display it. This was originally added for HTTP streaming, but we can leverage it nicely as well. You can read more about it here.

Solution #1 (Basic)

Sender | Receiver | Tester (both in frames) | FLV video for testing

In this demo, you browse for a FLV video on a local storage device; once you choose it, it starts providing packets for other peers.

sender-receiver

Basically, you cut video into chunks and start providing it using NetGroup.addHaveObjects(0, 84); - this video has 84 chunks. On the receiver side, you ask for a zero chunk, which is a file descriptor, using NetGroup.addWantObjects(0,0); In this descriptor you receive the total chunks count and you can add more info like file name, size, etc. Once you receive the zero chunk, you ask for the rest of the objects using NetGroup.addWantObjects(1,84); and Flash Player will start receiving the rest of the packets after a few seconds.

Try opening the receiver in other 5 or more windows and you will find an error. There is no guarantee that packets are received one by one, they can be received in completely different order and for this, you will need a special buffer. More in Advanced solution below.

Solution #2 (Advanced)

App demo | Tester (four apps)

This solution is the main concept of P2P VOD. One peer downloads a FLV video from a server using URLStream. While downloading, it starts providing the video for others and others starts receiving the video and providing as well.

app-demo


The Challenges

There were couple challenges, which need to be addressed to make it work properly.

Chunks
You need to split received bytes from URLStream to deliverable chunks. You have to wait until you receive at least one chunk (64KB) and than add it to an array. If you receive less, you wait, until you have 64 KB or more and then you add it. (So - First buffer). If you receive more than 64 KB in one progress event, you need to cut it in a cycle. So for instance if you receive 100 KB, you create one chunk (64 KB) and the rest (36 KB) you leave in the buffer to be filled (to at least 64 KB).  If you receive 200 KB (you create 3 chunks and keep 8 KB for the next batch). If you receive last bits of the data, which is in Event.COMPLETE, than you create just final chunk (which is always going to be less than 64 KB or same). All these things are done in URLByteLoader.as. Check especially createChunks() function.

schema-file-receive-urlstream

Download buffer for viewing
While downloading, I put chunks into a buffer, which is appended directly to the NetStream and then played in a Video object. This enables me to display video during the download process.

Postponed buffer for P2P (put chunks together)
The biggest problem with receiving Object Replication packets is that there is no guarantee that you will receive packets in correct linear order one by one. Typically you receive packets a completely mixed order - e.g. 1,2,3,4,20,21,22,5,6,7 and so on. So you need a Timer that puts these packets together and waits for the next one in the line and then continues with appending bytes to the NetStream. This basically enables you to display video during the Object Replication process and you don’t have to wait until you receive all the packets before you start playing video.

Deciding who is provider
In the real world, you will need to decide who is the provider and who is the receiver. Providers should be clients on the best uplink/downlink network. You can make a network check before playing video and then say that this client is going to be a provider. You can save this information in cookies with a corresponding expire time.

The Source

Download here (src.zip, 10 KB)

Where to go from here

Check out these other tutorials on P2P in Flash:

- File Sharing over P2P in Flash Player 10.1 with Object Replication
- P2P GroupSpecifier Class Explained In Details Part 1
- Multicast Explained in Flash 10.1 P2P
- Directed Routing Explained in Flash 10.1 P2P
- Simple chat with P2P NetGroup in FP 10.1

Video tutorials:
- P2P Chat with NetGroup in Flash Player 10.1
- Multicast Streaming in Flash Player 10.1 Tutorial

Facebook comments:

26 Comments »

  1. This is pretty interesting stuff, the real acid test would be to see it in production.

    Comment by Ahmed Nuaman — July 29, 2010 @ 12:17 am

  2. [...] Go here to read the rest [...]

    Pingback by Video-on-Demand over P2P in Flash Player 10.1 with Object Replication | Flash Stock Files — July 29, 2010 @ 2:59 am

  3. Great article, congradulations =)

    Comment by Leonardo França — July 29, 2010 @ 6:04 am

  4. oh! very cool

    Comment by cooerson — July 29, 2010 @ 6:11 am

  5. [...] Direct Link [...]

    Pingback by Video-on-Demand over P2P in Flash Player 10.1 with Object Replication | Lively Flash Tuts — July 29, 2010 @ 8:33 am

  6. Hi tom,
    I want to use P2P between java and flash client. Is it possible by any means ?

    regards,
    ATIF

    Comment by Atif — July 29, 2010 @ 12:39 pm

  7. Hi Atif, I think currently not - RTMFP is currently only in Flash Player and it’s not yet open protocol due to security reasons. Maybe in the future.

    Comment by tom — July 29, 2010 @ 12:55 pm

  8. thanks tom nice article btw.

    Comment by Atif — July 29, 2010 @ 1:08 pm

  9. Can i publish local video to FMS as well or its only limited to P2P ?

    Comment by Atif — July 29, 2010 @ 1:13 pm

  10. Well - most probably yes. Using RTMP NetStream and passing byte array data.

    Comment by tom — July 29, 2010 @ 1:21 pm

  11. hi Tom,
    Can you please give any example in how to pass data.
    I am using appendBytes but it gives following error.

    TypeError: Error #2004: One of the parameters is invalid.
    at flash.net::NetStream/appendBytesAction()

    Comment by Atif — July 29, 2010 @ 2:36 pm

  12. Atif - read about it here: http://www.bytearray.org/?p=1689

    Comment by tom — July 29, 2010 @ 3:06 pm

  13. yes i have already read this article.But i think publishing stream to FMS is not yet possible. As i read the documentation of appendBytes (Passes a ByteArray into a NetStream for playout.)not publishing.

    Comment by Atif — July 29, 2010 @ 3:26 pm

  14. sure, but - you can load a local file into bytearray chunks and then pass these chunks via NetStream.send() to FMS, which distributes those packets to receivers. It shouldn’t be that complicated. I can prepare an example.

    Comment by tom — July 29, 2010 @ 4:08 pm

  15. Great article! The FP10.1 capabilities are amazing. Thanks!

    Comment by Snickers[PL] — July 29, 2010 @ 4:44 pm

  16. Using Arduino with Adobe Flash for Model Railroading: Part 2…

    I really found your post interesting so I added a trackback to it on my Track Hacker blog :)…

    Trackback by Track Hacker — July 30, 2010 @ 7:37 pm

  17. [...] Video-on-Demand over P2P in Flash Player 10.1 with Object Replication [...]

    Pingback by The next big thing: Adobe Flash P2P « Flash Video Technology and Optimizations — July 30, 2010 @ 8:05 pm

  18. Hi Tom,
    What should be appendBytes length.I am trying to use appendBytes with virtual file.But no success.Video player only Shows First Frame and the nothing after that.Any suggestions.

    regards,
    ATIF

    Comment by Atif — July 31, 2010 @ 11:20 am

  19. Hi Atif, I am not sure about this. But more bytes = better. I would provide bytes for at least couple seconds - which is by my opinion sufficient buffer. The minimum is defined by so many bytes, which can be played until you come to their end - and till that, you need to provide another more bytes to follow.

    Comment by tom — August 2, 2010 @ 11:22 am

  20. i just loaded a local file and on load complete i made different chunks of it and sending to the other client using NETSTREAM.SEND function

    FMS_ns.send(”RemoteApendStream”,bytarray);

    getting this error

    Error #2044: Unhandled AsyncErrorEvent:. text=Error #2095: flash.net.NetStream was unable to invoke callback RemoteApendStream. error=TypeError: Error #1034: Type Coercion failed: cannot convert Object@11820ee1 to flash.utils.ByteArray.

    please help me out.

    Comment by waqas — August 6, 2010 @ 1:03 pm

  21. Very nicely detailed. And to think, we were thinking of this possibility on a flight a couple of weeks back. But really, we really need rtmfp on FMS rather than just Stratus.

    Comment by Arindam Biswas — August 7, 2010 @ 10:54 pm

  22. To waqas:
    you can use ffmpeg to realize that.

    Comment by FMSer.CN — August 9, 2010 @ 9:44 am

  23. [...] Read also: Video-on-Demand over P2P in Flash Player 10.1 with Object Replication [...]

    Pingback by File Sharing over P2P in Flash Player 10.1 with Object Replication — FlashRealtime.com — August 18, 2010 @ 1:00 am

  24. Hello Tom.

    Thanks for the tutorial that is great.

    I have question. Is it possible to apply this concept to a live stream, like a webcam or something similar. I need to make this kind of file distribution but the source file is a webcam stream. Is it possible? Thanks for the help.

    Comment by João batalha — August 20, 2010 @ 12:02 pm

  25. Hi Joao, absolutely. But for live stream it’s better to use Multicast - read here: http://www.flashrealtime.com/multicast-explained-flash-101-p2p/

    Comment by tom — August 25, 2010 @ 6:06 pm

  26. Hello Tom.
    Thanks for the reply. I was already testing the example you gave me.
    The porpose of the project i’m working is this. I have a central server that is streaming a webcam source and there is a flash application there that is publishing it as a multicas stream. Then i need to have the clients (swf application served in a http server) to connect to this streaming server. I want to use this type of technology because we need to decreasing to the minimal level the amount of data transmitted between the server and a local network where several clients are connected. So the perfect solution would be:
    - for each local network the first client that connects to the streaming server will be the main “server” for the next one and so on..

    We have manage to build this type of structure and we are now beginning to test it, but all the clients belong to the same group so we can’t be sure that a client from a local network will serve and will be served by the clients of that corresponding network. understand?

    Is this possible using this type of technology and get to the objective we want?

    thanks.(you can use my email if you want)

    Comment by João batalha — August 26, 2010 @ 11:11 am

RSS feed for comments on this post. / TrackBack URL

Leave a comment