如何使用 gundb 存储图像/视频文件?

how to store image / video file using gundb?

我知道传统的方法是将 image/video 文件存储在一个地方,然后将引用索引保存到数据库的 table 中。

现在我正在学习gundb,我可以很容易地存储键值json类型的数据,但是由于它是去中心化的,如果我想做一个聊天室应用程序,我应该如何处理图像存储(例如:用户的头像)?

我也想知道是否可以使用 gundb 制作一个电影共享应用程序?

@Retric,好问题!我不确定为什么人们会对你投反对票,他们一定是仇恨者。

你是对的,最好存储 image/video 并通过 GUN 引用它。具体到视频,WebTorrent/BitTorrent 从事 P2P 视频共享已有十多年了,一度处理了全球 40% 的互联网流量!

但是 WebTorrent/BitTorrent 对于 discovering/sharing 那些 URI(磁力链接等)不是很好,但是 GUN 是。所以我建议将其作为一种选择。

对于图像,尤其是像 avatars/icons/profiles 这样的小图像,我经常通过 Base64 编码将它们直接存储在 GUN 中(世界上许多网站将 images/icons/sprites/avatars 内联到 CSS 带有 base64 数据 URL 的文件,除了现在你可以为此使用 GUN)。

如果您对此感兴趣,我使用 jQuery 编写了一个小实用程序,可让您将图像拖放到您的网站中,它会自动调整大小(传递选项以覆盖它)并对其进行 base64 编码然后保存到 GUN:

https://github.com/amark/gun/blob/master/lib/upload.js

这是我如何使用它的一个小例子:

$('#profile').upload(function resize(e, up){
    if(e.err){ return } // handle error
    $('#profile').addClass('pulse'); // css to indicate image processing
    if(up){ return up.shrink(e, resize, 64) } // pass it `e` drag&drop/upload event, then I reuse the current function (named resize) as the callback for it, and tell it resize to 64px.
    $('#profile').removeClass('pulse'); // css indicate done processing.
    $("#profile img").attr('src', e.base64).removeClass('none'); // set photo in HTML!
    gun.user().get('who').get('face').get('small').put(e.base64); // save profile thumbnail to GUN
});

最后,如果不想使用 BitTorrent,将视频存储在 GUN 中如何?

我强烈建议使用 HLS 格式在 GUN 中存储视频,这将允许您进行去中心化的实时视频流。这是一种非常简单的格式,甚至可以从静态文件中进行视频流式传输,因为它将视频存储在可以流式传输的小块中 - 这非常适合 GUN。

已经有一个基于 JS 的 HLS 格式视频播放器:

https://github.com/video-dev/hls.js/

基于演示页面,您可以看到视频存储方式的示例,例如 GitHub:

https://github.com/video-dev/streams/tree/master/x36xhzz

(如果你点击 m3u8 文件,你会看到它有 720p 的元数据存储在 url_0 文件夹中,它们本身有子文件)

与其将 HLS 视频文件存储在 BitTorrent 或中央服务器上,不如使用相同的文件夹结构 gun.get('videos').get('x36xhzz').get('url_0').get('url_496').get('193039199_mp4_h264_aac_hd_7.ts').once(function(video_chunk){ passToHLSplayer(video_chunk) }) 将其存储在 GUN 中,这样 HLS.js 可以很容易地与枪.

现在您将拥有 P2P 去中心化视频流!!!

更酷的是,您可以将它与 GUN 的 lib/webrtc 适配器结合使用,并在浏览器之间完成此操作!

希望对您有所帮助。

这里要理解的是content addressed space (frozen space) and user space和gun的区别

假设您有一些编码为 base64 的媒体,并且您知道其内容类型(我在此处使用文本来简化示例,但您可以使用图像视频等):

// put avatar in frozen space:
let media = JSON.stringify({ b64 : "U2hlIHdhcyBib3JuIGFuIGFkdmVudHVyZXIuLi4=", type : "text/plain"})
// get hash of stringified media obj using gun's SEA lib:
let mediaID = await SEA.work(media, null, null, {name: "SHA-256"});
// put media in hash-addressed gundb
gun.get('#').get(mediaID).put(media,(r)=>console.log('Media put acknowledged?',r))

对于假设的聊天应用程序,您可以使用 user space 并将媒体放在“头像”名称下:

// put avatar in user space:
let user = await SEA.pair();
await gun.user().auth(user) 
gun.get('~' + user.pub).get('avatar').put('#' + mediaID)

// retrieve a user's avatar
gun.get('~' + usera.pub).get('avatar').once((hashid,k)=>{
    gun.get('#').get(hashid).once(media=>{
      console.log("Got user's avatar :-)",media)
      //do something with media
    })
})