NBC环球黑客马拉松-迈阿密2018

这个周末,我去花了一些时间在“ NBC Universal Hackathon”上破解一些代码,并尝试了一些新的想法,结识了新朋友,并在许多技术方面和创新上学到了很多。 我们决定要解决的特定问题是当前电视的无关紧要的方面,以及与现有技术的互动性如何。 通过协作体验解决问题的方法,用户可以通过屏幕上显示的视频与手机和相机进行交互。

该小组由以下成员组成:萨蒂亚,保罗·瓦尔德兹,胡安·古斯,我自己和克里斯。

我们做的很简单,我们可以创建一个网站,该网站可以包含可以进行效果处理的画布,在其中添加电视/视频提要,并使用“云到有线电视”等平台将内容分发给有线电视运营商或OTT / IPTV系统。

该解决方案需要设置和配置以下几项:

  • RTMP Server或WebRTC设置以接收来自智能手机或笔记本电脑的视频供稿,
  • FFMPEG编码,压缩和发布视频/音频提要
  • 带有RTMP客户端或WebRTC客户端或笔记本电脑的移动应用。 我们尝试了几次,但这个结果还可以。
  • Python中的Web应用程序,用于映射每个提要并将其定位在TV Channel视频源的顶部(假设是M3U8提要或MP4中的电影)

有了这个,编译CRTMP,FFMPEG就很重要了,我们尝试了深度学习等其他组件,例如“ Deep Fakes”项目。 我们的想法是替换一位演员的图像,并将我们的实时供稿叠加到视频中。

问题:

  • Safari浏览器不允许您播放具有自动播放功能的内容,这意味着用户必须启动播放。 如果SAFARI看到或检测到onLoad内容会自动播放,则将失败。
  • SAFARI存在问题,会动态加载内容和视频。oncanplaythrough( )必须添加到javascript中。

实时Feed大约需要延迟30-40秒,因为它必须:

  • 从手机转换并推送到RTMP服务器,
  • 抓取RTMP并将其作为m3u8编码的文件发送到网站。

标准的CRTMP屏幕将看起来很像,并且Gus和Pablo的连接成功完成:

+-----------------------------------------------------------------------------+ | Services| +---+---------------+-----+-------------------------+-------------------------+ | c | ip | port| protocol stack name | application name | +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 1112| inboundJsonCli| admin| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 1935| inboundRtmp| appselector| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 8081| inboundRtmps| appselector| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 8080| inboundRtmpt| appselector| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 6666| inboundLiveFlv| flvplayback| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 9999| inboundTcpTs| flvplayback| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 5544| inboundRtsp| flvplayback| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 6665| inboundLiveFlv| proxypublish| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 8989| httpEchoProtocol| samplefactory| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 8988| echoProtocol| samplefactory| +---+---------------+-----+-------------------------+-------------------------+ |tcp| 0.0.0.0| 1111| inboundHttpXmlVariant| vptests| +---+---------------+-----+-------------------------+-------------------------+ 

我们试图使用WebRTC,但存在许多延迟和延迟问题。

演示所需的FFMPEG命令是:

 ffmpeg -re -i rtmp://96.71.39.58/live/pablo -c:v libx264 -c:a aac -ac 1 -strict -2 -crf 18 -profile:v baseline -maxrate 200k -bufsize 1835k -pix_fmt yuv420p -flags -global_header -hls_time 3 -hls_list_size 4 -hls_wrap 10 -start_number 1 /var/www/html/live/pablo.m3u8 ffmpeg -re -i rtmp://96.71.39.58/live/gus -c:v libx264 -c:a aac -ac 1 -strict -2 -crf 18 -profile:v baseline -maxrate 200k -bufsize 1835k -pix_fmt yuv420p -flags -global_header -hls_time 3 -hls_list_size 4 -hls_wrap 10 -start_number 1 /var/www/html/live/gus.m3u8 

移动应用在服务器的/ live / pablo和/ live / gus下发布了RTMP流。 演示视频,内容如下:

使用Safari在Vimeo中截屏

要在具有3个屏幕的FFMPEG的Mac中进行屏幕捕获,请列出设备并进行捕获,以避免任何MOOV问题和无用的MOV / MP4文件。

 ffmpeg -f avfoundation -list_devices true -i "" ffmpeg -f avfoundation -i "3:0" -t 120 -pix_fmt yuv420p -c:v libx264 -c:a libmp3lame -r 25 teleport.mov 

我们的演示文稿可以在这里找到:

https://docs.google.com/presentation/d/1sKAvnC-Y-KHu2qclulH2Fp-8yWvTslq6bLaocyEgtfQ/edit?usp=sharing

源代码包含一个使用DOM对象,视频源和画布的HTML站点。 如图所示,视频是隐藏的,它是一种本机格式,可以使用画布绘图从m3u8,MOV,MP4或浏览器可以处理的任何格式的“ src”中复制视频。 然后,画布是所有叠加层和div的占位符。 使用画布的想法是,消息随后可以作为WhatsApp应用程序或使用画布的任何其他聊天应用程序在用户之间键入和交换。

  var canvas = document.getElementById(“ c”); 
var context = canvas.getContext(“ 2d”);
  var splayer = {}; 
 函数showIt(id,url,hideOrNot){ 
console.log(id +“” + url +“设置为” + hideOrNot);
splayer [“ v _” + id] = document.getElementById(“ v _” + id);
document.getElementById(id).style.display = hideOrNot;
 如果(document.getElementById(id).style.display ==“ none”){ 
document.getElementById(id).style.display =“ block”;
var vId =“ vsrc _” + id;
console.log(“正在播放” + vId +“” + url);
document.getElementById(vId).src = url;
 如果(splayer [“ v _” + id] .paused){ 
console.log(“视频已暂停。...”);
splayer [“ v _” + id] .load();
splayer [“ v _” + id] .oncanplaythrough = function(){
splayer [“ v _” + id] .play();
};
}其他{
console.log(“视频已经在播放...”);}
  }其他{ 
console.log(“正在停止...。v _” + id);
splayer [“ v _” + id] .pause();
document.getElementById(id).style.display =“ none”;
}
  } 
  var player = document.getElementById(“ v”); 
 函数ChangeHarry(){ 
console.log(“正在玩Harry Potter ....”);
document.getElementById(“ vsrc_main”)。src =“ http://s3.us-east-2.amazonaws.com/teleportme/videos/HarryPotterClip.mp4”;
player.load();
player.play();
drawVideo(context,player,canvas.width,canvas.height);
}
 函数ChangeQueen(){ 
console.log(“正在打南方皇后...”);
player.pause();
document.getElementById(“ vsrc_main”).src =“ http://96.71.39.58/queen0.mp4”;
  player.load(); 
player.play();
}
  setTimeout(function(){ 
showIt(“第一”,“ https://mediamplify.com/teleport/iwantharry.mp4”,“无”);
setTimeout(ChangeHarry,6000);
},2000);
  setTimeout(function(){ 
showIt(“第一”,“ https://mediamplify.com/teleport/iwantharry.mp4”,“阻止”);
},8000);
  setTimeout(showIt,5000,“ second”,“ http://96.71.39.58/live/pablo.m3u8”,“ none”); 
  setTimeout(showIt,6000,“ third”,“ http://96.71.39.58/live/gus.m3u8”,“ none”); 
  console.log(“开始更改内容”); 
  setTimeout(function(){ 
console.log(“准备切换到南方女王”); showIt(“ first”,“ https://mediamplify.com/teleport/iwantqueen.mp4”,“ none”);
},13000);
  setTimeout(showIt,15000,“ third”,“ http://96.71.39.58/live/pablo.m3u8”,“ none”); 
  setTimeout(showIt,15010,“ second”,“ http://96.71.39.58/live/gus.m3u8”,“ none”); 
  setTimeout(function(){ 
console.log(“南方皇后”);
ChangeQueen();
showIt(“ first”,“”,“ block”);
},19000);
 函数drawVideo(上下文,视频,宽度,高度){ 
context.drawImage(video,0,0,width,height); //将当前视频帧绘制到canvaz
var delay = 100; //延迟毫秒数以降低帧速率
setTimeout(drawVideo,delay,context,video,width,height); //延迟后再次递归调用drawVideo()
  } 

对于功能演示,第一个允许站点以自动播放方式播放视频:

Teleport ME-Mediamplify.com上的演示

我们没有获胜,但是做起来很有趣! 我们的演讲失败了,只有3分钟,演讲者在最后一分钟消失了,Gus即兴表演,并没有使用法官提供的所有时间。 我们知道当没有问题时我们就完成了。 …。 无论如何!!! 你不可能总是赢。