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

17

我知道传统的方法是将图像/视频文件存储在一个地方,然后只保存引用索引到数据库的表中。

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

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

2个回答

22

@Retric,好问题!我不确定为什么人们会给你点踩,他们一定是仇恨者。

你说得对,最好将那些图像/视频存储起来,并通过GUN进行引用。特别是对于视频,WebTorrent / BitTorrent已经进行了P2P视频共享超过十年,并且曾经处理过全球40%的互联网流量!

然而,WebTorrent / BitTorrent在发现/共享这些URI(磁力链接等)方面并不是很好,但GUN是。因此,我建议将其作为一种选择。

对于图像,尤其是小的头像/图标/个人资料之类,我经常直接将它们存储在GUN中,通过对它们进行Base64编码(世界各地有许多网站将图像/图标/精灵/头像内联到带有base64数据URL的CSS文件中,现在您可以使用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完美匹配。

已经有了基于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中,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) }),这样HLS.js就可以轻松集成到GUN中。

现在您将拥有P2P分散式视频流!

更酷的是,您可以将其与GUN的lib/webrtc适配器相结合,并完全通过浏览器完成此操作!

我希望这有所帮助。


3
谢谢,这对我帮助很大!我会查看HLS格式,使用Base64方式存储头像实际上非常方便。 - Retric

1
这里需要理解 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))

对于一个假想的聊天应用,你可以使用“用户空间”,并将媒体放在“头像”名称下面:
// 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
    })
}) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接