为视频添加时间戳

发布于 2024-12-16 16:10:24 字数 222 浏览 0 评论 0原文

我正在开发一个应用程序,从帧捕获卡捕获完整的高清视频并将其保存到磁盘上的文件中。我使用 Diretshow 接口捕获视频流,对其进行编码,然后使用 AVI Mux 过滤器将其保存到磁盘。

现在我还想将时间戳(捕获视频的时间)添加到视频文件中,以便当用户稍后播放视频文件时,时间戳在视频顶部可见。用户应该能够播放任何流行的播放器(VLC、Windows 媒体播放器等)。任何人都可以帮助我找到完成这项任务的可能方法。

I am working on an application where I am capturing a full HD Video from a framegrabber card and saving it to a file on disk. I am using Diretshow interfaces to capture the video stream, encode it and then using AVI Mux filter I am saving it to the disk.

Now I also want to add the timestamp(time when video was captured) to the video file, so that timestamp is visible on the top of video when user plays the video file later. And user should be able to play it any popular players(VLC, Windows media player etc.). Can anyone help me with possible methods for achieving this task.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花落人断肠 2024-12-23 16:10:24

您可以为此编写自己的过滤器,该过滤器继承自 CTransInPlaceFilter。覆盖 Transform 方法,您可以在其中使用 GDI+ 在位图顶部写入时间戳。

您必须将此过滤器连接到图表中的适当位置,即媒体类型为 RGB 的位置。

编辑:
下面是从我的过滤器中提取的一些示例代码,用于在 RGB 帧上写入文本。
希望这可以帮助您开始:

#include <Gdiplus.h>
...
using namespace Gdiplus;

HRESULT UtilityFilter::Transform(IMediaSample *pSample)
{
  ...
  std::string sText = ...
  return drawTextOntoFrame(sText, pSample); 
}

HRESULT UtilityFilter::drawTextOntoFrame(const std::string& sText, IMediaSample *pSample)
{
  // get image properties
  AM_MEDIA_TYPE mt;
  HRESULT hr = InputPin()->ConnectionMediaType(&mt);
  if (FAILED(hr))
  {
    return hr;
  }
  ASSERT(mt.formattype == FORMAT_VideoInfo);
  BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);

  // Get image buffer
  BYTE *pBuffer(NULL);
  hr = pSample->GetPointer(&pBuffer);
  if (FAILED(hr))
  {
    return hr;
  }

  wchar_t* wsText = StringUtil::stlToWide(sText);

  BITMAPINFO bitmapInfo;
  bitmapInfo.bmiHeader = *pbmi;

  Bitmap bm(&bitmapInfo, (void*)pBuffer);
  Graphics* pGraphics = Graphics::FromImage(&bm);

  // Initialize font
  Font myFont(L"Arial", 16);
  //RectF layoutRect(0.0f, 0.0f, 200.0f, 50.0f);
  RectF layoutRect(m_uiX, m_uiY, 350.0f, 50.0f);
  StringFormat format;
  format.SetAlignment(StringAlignmentNear);
  SolidBrush blackBrush(Color(255, 0, 0, 0));
  SolidBrush greenBrush(Color(255, 0, 255, 0));

  // Draw string
  pGraphics->DrawString(
    wsText,
    sText.length(),
    &myFont,
    layoutRect,
    &format,
    &greenBrush);

  delete[] wsText;
  delete pGraphics;
  return S_OK;
}

You can write your own filter for this that inherits from CTransInPlaceFilter. Override the Transform method and in it you can write the time stamp on top of the Bitmap using GDI+.

You would have to connect this filter in the appropriate position in the graph i.e. somewhere where the media type is RGB.

EDIT:
Here's some sample code ripped from a filter of mine for writing text on an RGB frame.
Hopefully that should get you started:

#include <Gdiplus.h>
...
using namespace Gdiplus;

HRESULT UtilityFilter::Transform(IMediaSample *pSample)
{
  ...
  std::string sText = ...
  return drawTextOntoFrame(sText, pSample); 
}

HRESULT UtilityFilter::drawTextOntoFrame(const std::string& sText, IMediaSample *pSample)
{
  // get image properties
  AM_MEDIA_TYPE mt;
  HRESULT hr = InputPin()->ConnectionMediaType(&mt);
  if (FAILED(hr))
  {
    return hr;
  }
  ASSERT(mt.formattype == FORMAT_VideoInfo);
  BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);

  // Get image buffer
  BYTE *pBuffer(NULL);
  hr = pSample->GetPointer(&pBuffer);
  if (FAILED(hr))
  {
    return hr;
  }

  wchar_t* wsText = StringUtil::stlToWide(sText);

  BITMAPINFO bitmapInfo;
  bitmapInfo.bmiHeader = *pbmi;

  Bitmap bm(&bitmapInfo, (void*)pBuffer);
  Graphics* pGraphics = Graphics::FromImage(&bm);

  // Initialize font
  Font myFont(L"Arial", 16);
  //RectF layoutRect(0.0f, 0.0f, 200.0f, 50.0f);
  RectF layoutRect(m_uiX, m_uiY, 350.0f, 50.0f);
  StringFormat format;
  format.SetAlignment(StringAlignmentNear);
  SolidBrush blackBrush(Color(255, 0, 0, 0));
  SolidBrush greenBrush(Color(255, 0, 255, 0));

  // Draw string
  pGraphics->DrawString(
    wsText,
    sText.length(),
    &myFont,
    layoutRect,
    &format,
    &greenBrush);

  delete[] wsText;
  delete pGraphics;
  return S_OK;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文