流式 RTSP(AspNet 5 API、FFMPEG、Angular 10、videoJs)[已解决]
Posted
技术标签:
【中文标题】流式 RTSP(AspNet 5 API、FFMPEG、Angular 10、videoJs)[已解决]【英文标题】:Streaming RTSP (AspNet 5 API, FFMPEG, Angular 10, videoJs) 【发布时间】:2022-01-23 01:38:51 【问题描述】:说明:
我有一个通过 RTSP 连接到 IP 摄像机的 API (ASP.Net 5)。摄像头发送一个用 ffmpeg 转换的 h264 流作为 m3u8 流返回给 Angular 客户端,如下所示:
public async Task<ActionResult> GetCameraH264Stream()
string deviceIp = "rtsp://[CAMERA_IP]/";
string recordingUri = "rtsp://[USER:PASSWORD]@[CAMERA_IP]/axis-media/media.amp";
string output = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".m3u8");
var mediaInfo = await FFmpeg.GetMediaInfo(recordingUri);
var conversionResult = FFmpeg.Conversions.New()
.AddStream(mediaInfo.Streams)
.SetOutput(output)
.Start();
// Allow any Cors
Response.Headers.Add("Access-Control-Allow-Origin", "*");
Response.Headers.Add("Cache-Control", "no-cache");
// Open the file, and read the stream to return to the client
FileStreamResult result = new FileStreamResult(System.IO.File.Open(output, FileMode.Open, FileAccess.Read, FileShare.Read), "application/octet-stream");
result.EnableRangeProcessing = true;
return result;
如果我直接调用这个方法,浏览器会下载一个文件,我可以用 VLC 读取。
在我的 Angular 应用中,我有这个组件:
app-vjs-player
@Component(
selector: 'app-vjs-player',
template: '<video #target class="video-js" controls muted playsinline preload="none">
</video>',
encapsulation: ViewEncapsulation.None,
)
export class VjsPlayerComponent implements OnInit, OnDestroy
@ViewChild('target', static: true) target: ElementRef;
@Input() options:
fluid: boolean,
aspectRatio: string,
autoplay: boolean,
sources:
src: string,
type: string,
[],
vhs:
overrideNative: true
,
;
player: videojs.Player;
constructor(
private elementRef: ElementRef,
)
ngOnInit()
// instantiate Video.js
this.player = videojs(this.target.nativeElement, this.options, function onPlayerReady()
console.log('onPlayerReady', this);
);
ngOnDestroy()
// destroy player
if (this.player)
this.player.dispose();
这个组件是这样使用的:
TS
playerOptions =
fluid: false,
aspectRatio: "16:9",
autoplay: false,
sources: [
src: 'https://localhost:44311/api/GetCameraH264Stream',
type: 'application/x-mpegURL',
],
HTML
<app-vjs-player #videoJs [options]="playerOptions"></app-vjs-player>
问题
这一切似乎都很好,直到 vjs 在 api 返回流时抛出此错误:
错误:(CODE:4 MEDIA_ERR_SRC_NOT_SUPPORTED) 无法加载媒体,可能是因为服务器或网络出现故障或格式不受支持
当我打开网络开发工具时,请求状态是“已取消”,但我不知道videojs是否因为无法读取filestreal而取消它,或者是因为API返回的方式流。
有什么想法吗?
来源
Forwarding RTSP stream from IP Camera to Browser in ASP.NET Core
VideoJs Angular integration
Xabe.FFMPEG
编辑
我试图限制分辨率和比特率,但我不能这样配置相机,有其他应用程序在使用它。相机没有任何允许此配置的流式传输 url 在更改 api 响应的内容类型后,我已经能够从我的代码中获取图像。我改变了:FileStreamResult result = new FileStreamResult(System.IO.File.Open(output, FileMode.Open, FileAccess.Read, FileShare.Read), "application/octet-stream");
到
FileStreamResult result = new FileStreamResult(System.IO.File.Open(output, FileMode.Open, FileAccess.Read, FileShare.Read), "application/x-mpegURL");
这样会显示第一个数据包,但仍会取消下一个请求。
【问题讨论】:
可能是服务器或者网络故障,或者格式不支持。这篇文章和你的情况差不多,希望对你有所帮助:github.com/videojs/video.js/issues/4751 嗨,你链接的 github 问题是关于 android/tablet 不兼容,这不是我的问题。但是有这样的评论:“我也猜想原因是元数据错误。就像你说的:高比特率,每秒帧数太多。”。我会尝试限制这一点并编辑结果 您的浏览器有问题吗? 我在企业网络下,所以只能用chrome和edge。我两个都有同样的问题 【参考方案1】:响应 ContentType 的更改正在起作用(请参阅问题的最后编辑)。
取消的请求似乎是由于网络缓慢。上面的所有代码都按原样工作,除了最后一个 modif ( application/octet-stream => application/x-mpegURL )。这是更新的api方法:
public async Task<ActionResult> GetCameraH264Stream()
string deviceIp = "rtsp://[CAMERA_IP]/";
string recordingUri = "rtsp://[USER:PASSWORD]@[CAMERA_IP]/axis-media/media.amp";
string output = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".m3u8");
var mediaInfo = await FFmpeg.GetMediaInfo(recordingUri);
var conversionResult = FFmpeg.Conversions.New()
.AddStream(mediaInfo.Streams)
.SetOutput(output)
.Start();
// Allow any Cors
Response.Headers.Add("Access-Control-Allow-Origin", "*");
Response.Headers.Add("Cache-Control", "no-cache");
// Open the file, and read the stream to return to the client
FileStreamResult result = new FileStreamResult(System.IO.File.Open(output, FileMode.Open, FileAccess.Read, FileShare.Read), "application/x-mpegURL");
result.EnableRangeProcessing = true;
return result;
【讨论】:
以上是关于流式 RTSP(AspNet 5 API、FFMPEG、Angular 10、videoJs)[已解决]的主要内容,如果未能解决你的问题,请参考以下文章