IPFS & HLS (chunking content)

I am building a video distribution platform and looking at IPFS. I have been experimenting for a while now. I have noticed one issue that bothers me. I use ffmpeg to chunk content into 60-second HLS segments (.ts files). I encrypt the content. In one case, I have a movie that chunks into 93 files. Each file is between 8 meg and 16 meg. I have a script that calls the remote APIs to add the files to my node running at DigitalOcean.

  1. If I upload the entire file (locally with ipfs add), I can stream it or download the segments. It takes a little time, but not much, for the entire file to be streamable. I have tested this many times over the last few weeks. I am using ipfs.io to test the distribution of the content. I had friends to test the stream all over the world.
  2. If I upload the 93 .ts chunk files via the API, The first file (the m3u8 file) and about 19% of the first .ts file is accessible after a few minutes. However, 24 hours later, I am still unable to access the remaining files, and the content is not streamable.

I am still tinkering. I would appreciate any advice or direction. The video test file is 1.1 GB in size.

BTW: If I connect directly to my node (configured as a gateway on port 8080), everything works fine because the content is pinned to my node. I do update the m3u8 file to point to the segments in IPFS. I test pointing to ipfs.io and my node.

Just a guess, but, one would imagine you are being rate limited since ipfs.io did not sign up to distribute your large video files. Any public gateway is going to stop this if they detect it. Spin up a dedicated gateway of your own for this.

Interestingly, the file is fine when it is a single, large file.

I have my gateway, but it is small now as I am in the early development stages. It is based in NYC and is hosted by DO.

I have a question: If I run my gateways when I deploy the service, will this bypass regional caching? If I reference my gateway in the m3u8 files, will it not always pull from my gateway since I will have the content always pinned?

I just ran a script to do an analysis. Twenty-one files were accessible. Three files were partially cached.

Thanks for your quick response. I am still learning.

– Jamey

What version of Kubo are you running ? You want to be sure it’s atleast 0.22 since it has a log message that warn you if your node is falling behind DHT announcements, which can make files unvailable on the network similar to that.

BTW Kubo supports range requests and streaming, so you don’t need hls to get good performance.
In the future I want to add content-aware chunking that means different video informations, audio tracks, video regions would be chunked around in the merkle tree.

I upgraded from .21 to .22 yesterday, both nodes. Thanks for the log tip.

I am using HLS for encryption. I will implement MSE in the website and app to decrypt it on the fly. I prefer 10-second chunks, but to be kind to IPFS, I made them 60 seconds.

Yes, I can stream the content just fine if it is not in HLS and encrypted via ipfs.io. Everything works fine when I put my gateway in the .m3u8 file. My issue is when I access via ipfs.io or dweb.link. And maybe that is not an issue if I use my gateways. I might be overthinking the issue.

Again, thanks.

BTW (accidentally posted before I was done): In the final product, decryption keys will be in a user’s crypto wallet as a token. For testing, I am embedding the decryption key in the .m3u8 file via a link to another file on IPFS.

– Jamey

The default chunk size is 256KiB, if your 60 second is bellow that IPFS is gonna rechunk it in it’s merkle tree.
If you want to be as efficient as possible for IPFS use --raw-leaves and make your chunks about 256KiB, better chunks can be more efficient but it’s at the risk of wasting more bandwidth since chunks can only be transfered whole for now.
You can also up the chunk size with --chunk=size-$NUMBERINBYTES which should be kept under 1MiB for now.

1 Like

I am using ffmpeg to chunk the file into .ts files. Because it is chunking an mp4 file, the chunk sizes vary. Sixty seconds is between 8 and 16 MB. 10 seconds is between 700K and 3 MB. And it will vary depending on the content.

I also see that you are speaking of IPFS chunks. I will study IPFS chunking.

I am using my gateway now. It is working great. Have a look using your favorite media player. I am testing with VLC and Dragon:

1 Like

I’ve got it working with the video tag. HLS.js and a little code did the trick:
I’ll have it secured with SSL shortly.


This is great work and thanks for sharing your process and progress :smiley:

1 Like

Hey, well done there, @jkirby !

Have you experimented to see if there is much improvement in the stream if several people are streaming at the same time?

Not yet. I’ve only had three or four folks streaming around the world. My server is also small for now while I am in development. The plan is to run multiple IPFS servers around the world configured to scale. They will all be connected in “bootstrap.”

I am still not sure how long I should make each segment. Right now, I am using 10 seconds. I also need to test with 4K and 8K content.

But I am streaming encrypted HLS content from IPFS! I am sure IPFS will work for my project.

We’ve secured the gateway and associated it with a temporary domain name. Everyone is welcome to hit. The background video (which will eventually be a teaser) will play in the background but will be blurred. If you connect with your crypto wallet, the video will unblur. Once unblurred, you will see the ‘buy’ and ‘play trailer’ buttons. They do nothing right now. You will also see the mute and unmute icons on the screen; they work.

The video is something I pulled from archive.org. I am using it for testing.

The content is encrypted before I upload it. It is decrypted in your web browser. Currently, the decryption key is in IPFS, and a link is in the m3u8 file. After the smart contracts side is done, I will implement decryption via MSE and the user’s crypto wallet.


From Brave, you can use:


I have tested with MetaMask wallet and Brave Wallet.

I’ll keep everyone updated as I make progress. I am thinking through my next steps.

– Jamey


I’ve written a little somethin-somethin about my approach to using IPFS for my project:

– Jamey

1 Like


Please please please don’t.

IPFS should be content agnostic. It should handle a video file exactly the same as a zip file or any other file. Also, this very much relies on the idea that IPFS is used in purely public scenarios. It would work for those scenarios, true.

But the real IPFS adoption is when you can easily use private data (thus encrypted) on the IPFS network. Making IPFS essentially a distributed transport layer, which it imho should strive to be!

Adding protocol fancy feature like content-aware chunking is not going to be good in the long term. It just makes the protocol more complex and just bloats the IPFS implementation side for features it shouldn’t have. A content-aware chunking mechanism would need to be different for every specific type of file. Even if you were to do content aware chunking, how would you determine a “good” variant of it? HLS on it’s own has many different forms of chunking (static, as in x seconds chunk, dynamic chunks and so many subtle variants).

And that’s only HLS. Then in video land you have a couple different ones too, most notable DASH but there’s more lesser known ones.

Lastly, as another motivation to not do this, chunks depend on how you set those chunks up on the ffmpeg/chunker side. How are you going to make these (ffmpeg + ipfs) play nice?


I, too, agree. Using HLS is easy, widely supported, and does what is needed for streaming. I would not make IPFS content aware. My stuff is working great with HLS on IPFS!

1 Like