B4J Question Securely decrypt and stream video for playback

hanyelmehy

Well-Known Member
Licensed User
Longtime User
Hello,

I’m working on a B4J desktop app where I need to play encrypted video files securely.
  • I already wrote working EncryptFile / DecryptFile subs using B4XCipher.
  • The problem is: when I decrypt, the only way I found is to write the full decrypted video to a temp file, then play it with MediaPlayer.
  • This is not secure, because the user can copy the decrypted video file from disk.
👉 My goal:
Decrypt the video in chunks and stream it directly to the MediaPlayer, so that the decrypted video is never saved as a file on disk.

any suggetion
 

hanyelmehy

Well-Known Member
Licensed User
Longtime User
Might be possible with PyBridge (I haven't tried and if it is possible then it will be with an external video player). With MediaView you will only be able to achieve it by implementing a media server.
If I create something using B4J and PyBridge, can I package it into a distribution or setup for clients? (I know this is easy to do with B4J only
 
Upvote 0

hanyelmehy

Well-Known Member
Licensed User
Longtime User
- i already try using python (uvicorn_server) ,but nothing in b4j can show/play this stream ,whic work fine on any other browser
Also, is there any way to embed a Chromium-based browser inside a B4J?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

zed

Well-Known Member
Licensed User
Your goal is ambitious but entirely achievable with B4J, Python and PyBridge, provided you properly orchestrate the flow between decryption and video playback.

The video is stored in encrypted form (e.g., AES) on disk or via streaming.
It is played in chunks in B4J.

MediaPlayer is expecting a file or URL
- One could use a temporary local server (e.g. jServer v4.0 - Based on Jetty 11) to expose the decrypted stream as a URL.

Decryption in memory
- Python can return chunks via PyBridge

You can create a small local HTTP server in B4J (using jServer v4.0) that serves the decrypted data on the fly. The MediaPlayer can then play from http://127.0.0.1:port/video.
This bypasses the MediaPlayer's limitation of not playing directly from an InputStream.

Here is a prototype of a system that could be built with pybridge.

Encrypted video storage
The video is stored locally or online in encrypted form (e.g., AES).
It can be played in chunks (pieces of a few KB or MB).

On-the-fly decryption with Python
B4J reads a chunk → sends it to Python via PyBridge.
Python decrypts the chunk in memory → returns the raw data to B4J.

Streaming to MediaPlayer
B4J starts a local HTTP server (Jetty or other).
This server serves the decrypted chunks on the fly.
The MediaPlayer plays the video via a local URL (http://127.0.0.1:8080/video).

Python side (AES decryption)
Python:
from Crypto.Cipher import AES

def decrypt_chunk(encrypted_chunk, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    return cipher.decrypt(encrypted_chunk)
You can call this function from B4J via PyBridge, chunk by chunk.

B4J side (pseudo-code)
B4J:
Sub Process_Globals
    Private py As Python
    Private server As Server
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    py.Initialize
    server.Initialize("local", 8080)
    server.AddHandler("/video", "VideoHandler", False)
    server.Start
    MediaPlayer.Load("http://127.0.0.1:8080/video")
    MediaPlayer.Play
End Sub

B4J Handler for /video
B4J:
Sub Handle(req As ServletRequest, resp As ServletResponse)
    Dim chunk() As Byte = ReadEncryptedChunkFromDiskOrStream()
    Dim decrypted() As Byte = py.RunFunction("decrypt_chunk", Array(chunk, key, iv))
    resp.OutputStream.WriteBytes(decrypted, 0, decrypted.Length)
End Sub

This function reads a chunk of encrypted video from a file or stream, without loading everything into memory.
B4J:
Sub ReadEncryptedChunkFromDiskOrStream() As Byte()
    ' Example: reading a 64 KB chunk from an encrypted file
    Dim raf As RandomAccessFile
    raf.Initialize(File.DirApp, "video.enc", False)

    Dim chunkSize As Int = 64 * 1024 ' 64 Ko
    Dim position As Long = GetNextChunkPosition() ' to be defined according to your reading system
    Dim buffer() As Byte = raf.ReadBytes(position, chunkSize)

    raf.Close
    Return buffer
End Sub

I remind you that this is only a prototype.
 
Upvote 0
Top