GVKun编程网logo

使用MediaElement播放Stream中的视频(如何使用mediaplayer播放视频)

24

本文将介绍使用MediaElement播放Stream中的视频的详细情况,特别是关于如何使用mediaplayer播放视频的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题

本文将介绍使用MediaElement播放Stream中的视频的详细情况,特别是关于如何使用mediaplayer播放视频的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于android – 如何使用MediaCodec,MediaExtractor或MediaMetadataRetriever确定视频文件的帧速率?、Android多媒体之使用MediaExtractor与MediaMuxer分离音视频、c# WPF设置软件界面背景为MediaElement并播放视频、c# – MediaElement支持哪些格式?的知识。

本文目录一览:

使用MediaElement播放Stream中的视频(如何使用mediaplayer播放视频)

使用MediaElement播放Stream中的视频(如何使用mediaplayer播放视频)

是否可以使用WPF MediaElement播放System.IO.Stream对象中的流视频?从存储媒体文件的WCF服务中检索Stream对象。

答案1

小编典典

如果可以使WCF通过传递媒体对象,http-URL (GET)则只需将该URL分配给MediaElement.Source属性-
请参见http://msdn.microsoft.com/zh-
cn/library/system.windows.controls.mediaelement.source。
aspx。

对于此类网址不可用/可能的情况:

当前无法分配流-
尽管有一些技巧可以实现这一点,有关基于DirectShow的示例,请参见http://social.msdn.microsoft.com/forums/en-
US/wpf/thread/6191ef1a-0010 -4294-a5b4-451bbadca33a
/和http://jmorrill.hjtcentral.com/Home/tabid/428/EntryId/15/WPF-
Hackery-
Part-I.aspx。

另一个选择是以某种方式托管SilverlightMediaElement并使用SetSource可以获取流并播放它的方法…请参阅http://silverlightviewport.codeplex.com/SourceControl/list/changesets和http://msdn.microsoft.com/
zh-cn / library / cc190669%28v = vs.95%29.aspx

android – 如何使用MediaCodec,MediaExtractor或MediaMetadataRetriever确定视频文件的帧速率?

android – 如何使用MediaCodec,MediaExtractor或MediaMetadataRetriever确定视频文件的帧速率?

如何提取录制视频文件的帧速率?我知道有MediaFormat.KEY_FRAME_RATE,我可以通过MediaExtractor访问MediaFormat对象.但是,KEY_FRAME_RATE仅适用于编码器.相反,我想找出已录制视频的帧速率.

有任何想法吗?

解决方法:

看起来没有办法通过任何官方API函数获得帧率.它可能需要一些额外的逻辑 – 时间戳之间的计数时间或解析头信息.通常,h.264标准允许可变帧率,因此帧时间可以从一对一不同.例如,如果可以显示一些静态图片几秒钟左右

Android多媒体之使用MediaExtractor与MediaMuxer分离音视频

Android多媒体之使用MediaExtractor与MediaMuxer分离音视频

MediaExtractor与MediaMuxer工具可以完美的将视频中的音视频分开来,可以对视频进行再配音合成达到自己的需求:

1.准备工作:声明基础变量

private final static String ROOT_PATH = Environment.getExternalStorageDirectory()
            .getAbsolutePath()+"/Media";
    private final static String MEDIA_DIVIDE_PATH = ROOT_PATH+"/divide";
    private final static String MEDIA_DUBBING_PATH = ROOT_PATH+"/dubbing";
    private String currentTaskPath = null;

    public final static String AUDIO_MIME = "audio";
    public final static String VIDEO_MIME = "video";

    private String videoOutputPath;

    public MediaDivider(){
        initOutputPath();
    }

    private void initOutputPath(){
        File file = new File(ROOT_PATH);
        if (!file.exists()) {
            file.mkdirs();
        }
        File divide = new File(MEDIA_DIVIDE_PATH);
        if (!divide.exists()) {
            divide.exists();
        }
        currentTaskPath = createCurrentTaskPath();
        File currentTask = new File(currentTaskPath);
        if (!currentTask.exists()) {
            currentTask.mkdirs();
        }
        File dubbingPath = new File(MEDIA_DUBBING_PATH);
        if (!dubbingPath.exists()) {
            dubbingPath.mkdirs();
        }
    }

    private String createCurrentTaskPath(){
        return MEDIA_DIVIDE_PATH+"/"+System.currentTimeMillis();
    }

2.开始分离音视频:

public void divideMedia(String sourceMediaPath,String divideMime){
        MediaExtractor mediaExtractor = new MediaExtractor();
        try {
            mediaExtractor.setDataSource(sourceMediaPath);
            int trackCount = mediaExtractor.getTrackCount();
            for (int i=0;i<trackCount;i++) {
                MediaFormat mediaFormat = mediaExtractor.getTrackFormat(i);
                String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
                if (!mime.startsWith(divideMime)) {
                    continue;
                }
                int maxInputSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
                Log.d(TAG,"maxInputSize:"+maxInputSize);
                ByteBuffer videoByteBuffer = ByteBuffer.allocate(maxInputSize);
                if (divideMime.equals(AUDIO_MIME)) {
                    Log.d(TAG,"divide audio media to file");
                    String audioName = currentTaskPath+"/"
                            +sourceMediaPath.substring(sourceMediaPath.lastIndexOf(''/'')+1,sourceMediaPath.lastIndexOf(''.''))
                            +"_audio_out.mp4";
                    Log.d(TAG,"audioName:"+audioName);
                    MediaMuxer mediaMuxer = new MediaMuxer(audioName,MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
                    int audioTrack = mediaMuxer.addTrack(mediaFormat);
                    mediaMuxer.start();
                    divideToOutputAudio(mediaExtractor,mediaMuxer,videoByteBuffer,mediaFormat,audioTrack,i);
                    finish(mediaExtractor,mediaMuxer);
                    break;
                } else if (divideMime.equals(VIDEO_MIME)) {
                    Log.d(TAG,"divide video media to file");
                    String videoName = currentTaskPath+"/"
                            +sourceMediaPath.substring(sourceMediaPath.lastIndexOf(''/'')+1,sourceMediaPath.lastIndexOf(''.''))
                            +"_video_out.mp4";
                    Log.d(TAG,"videoName:"+videoName);
                    MediaMuxer mediaMuxer = new MediaMuxer(videoName,MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
                    int videoTrack = mediaMuxer.addTrack(mediaFormat);
                    mediaMuxer.start();
                    divideToOutputVideo(mediaExtractor,mediaMuxer,videoByteBuffer,mediaFormat,videoTrack,i);
                    finish(mediaExtractor,mediaMuxer);
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

该方法接受视频路径与所要分离出的媒体文件格式:audio或者video,根据媒体格式进行操作。

3.分离视频:

private void divideToOutputVideo(MediaExtractor mediaExtractor,MediaMuxer mediaMuxer,ByteBuffer byteBuffer,MediaFormat format,
                                     int videoTrack,int videoTrackIndex) {
        long videoDuration = format.getLong(MediaFormat.KEY_DURATION);
        mediaExtractor.selectTrack(videoTrackIndex);
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        bufferInfo.presentationTimeUs = 0;
        long videoFrameTimes;
        mediaExtractor.readSampleData(byteBuffer,0);
        if (mediaExtractor.getSampleFlags()!=MediaExtractor.SAMPLE_FLAG_SYNC) {
            mediaExtractor.advance();
        }
        mediaExtractor.readSampleData(byteBuffer,0);
        mediaExtractor.advance();
        long firstFrame = mediaExtractor.getSampleTime();
        mediaExtractor.advance();
        mediaExtractor.readSampleData(byteBuffer,0);
        long secondFrame = mediaExtractor.getSampleTime();
        videoFrameTimes = Math.abs(secondFrame-firstFrame);
        mediaExtractor.seekTo(0,MediaExtractor.SEEK_TO_CLOSEST_SYNC);
        int sampleSize;
        while ((sampleSize=mediaExtractor.readSampleData(byteBuffer,0))!=-1){
            long presentTime = bufferInfo.presentationTimeUs;
            if (presentTime>=videoDuration) {
                mediaExtractor.unselectTrack(videoTrackIndex);
                break;
            }
            mediaExtractor.advance();
            bufferInfo.offset=0;
            bufferInfo.flags=mediaExtractor.getSampleFlags();
            bufferInfo.size=sampleSize;
            mediaMuxer.writeSampleData(videoTrack,byteBuffer,bufferInfo);
            bufferInfo.presentationTimeUs +=videoFrameTimes;
        }
        mediaExtractor.unselectTrack(videoTrackIndex);
    }

4.分离出音频:

private void divideToOutputAudio(MediaExtractor mediaExtractor,MediaMuxer mediaMuxer,ByteBuffer byteBuffer,MediaFormat format,
                                     int audioTrack,int audioTrackIndex){
        int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
        int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
        Log.d(TAG,"rate:"+sampleRate+",c:"+channelCount);
        long audioDuration = format.getLong(MediaFormat.KEY_DURATION);
        mediaExtractor.selectTrack(audioTrackIndex);//参数为多媒体文件MediaExtractor获取到的track count的索引,选择音频轨道
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        bufferInfo.presentationTimeUs = 0;
        long audioSampleSize;
        mediaExtractor.readSampleData(byteBuffer,0);
        if (mediaExtractor.getSampleTime()==0) {
            mediaExtractor.advance();
        }
        mediaExtractor.readSampleData(byteBuffer,0);
        long firstRateSample = mediaExtractor.getSampleTime();
        mediaExtractor.advance();
        mediaExtractor.readSampleData(byteBuffer,0);
        long secondRateSample = mediaExtractor.getSampleTime();
        audioSampleSize = Math.abs(secondRateSample-firstRateSample);
        mediaExtractor.seekTo(0,MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
        int sampleSize;
        while ((sampleSize=mediaExtractor.readSampleData(byteBuffer,0))!=-1) {
            int trackIndex = mediaExtractor.getSampleTrackIndex();
            long presentationTimeUs = bufferInfo.presentationTimeUs;
            Log.d(TAG,"trackIndex:"+trackIndex+",presentationTimeUs:"+presentationTimeUs);
            if (presentationTimeUs>=audioDuration){
                mediaExtractor.unselectTrack(audioTrackIndex);
                break;
            }
            mediaExtractor.advance();
            bufferInfo.offset=0;
            bufferInfo.size=sampleSize;
            mediaMuxer.writeSampleData(audioTrack,byteBuffer,bufferInfo);//audioTrack为通过mediaMuxer.add()获取到的
            bufferInfo.presentationTimeUs += audioSampleSize;
        }
        mediaExtractor.unselectTrack(audioTrackIndex);
    }

5.释放资源:

    private void finish(MediaExtractor mediaExtractor,MediaMuxer mediaMuxer){
        mediaMuxer.stop();
        mediaMuxer.release();
        mediaMuxer = null;
        mediaExtractor.release();
        mediaExtractor = null;
    }

c# WPF设置软件界面背景为MediaElement并播放视频

c# WPF设置软件界面背景为MediaElement并播放视频

    在我们的常见的软件界面设计中我们经常会设置软件的背景为SolidColorBrush或者LinerColorBrush、RadialGradientBrush 等一系列的颜色画刷为背景,有时我们也会使用ImageBrush添加图片来作为界面的背景,另外常用的还有DrawingBrush以及今天需要进行总结的VisualBrush,这些我们都是比较容易实现的,那么我们如果想将软件的界面设计成一个动画或者干脆播放一段视频作为背景,这个对于整个软件的效果又是一个巨大的提升。

    首先我们来看看background属性,MSDN上的解释是:获取或设置用于填充控件Control的边框之间的区域的 Brush。它的类型是:Type: System.Windows.Media.Brush,所以我们能够使用具有Brush属性的控件或者属性来作为背景来填充它。

    我们首先来看看前台样式的设计: 

<Window x:        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ui="clr-namespace:X.UI;assembly=X.UI"  
        xmlns:local="clr-namespace:TestBackGroundWorker"
        Title="MainWindow" Height="681" Width="1000">
    <Window.Resources>
        <Style TargetType="local:BackgroundPlayer">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:BackgroundPlayer">
                        <MediaElement x:Name="Media" Stretch="Fill"></MediaElement>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.Background>
            <VisualBrush>
                <VisualBrush.Visual>                   
                    <local:BackgroundPlayer Source="~/Images/bg.avi"></local:BackgroundPlayer>
                </VisualBrush.Visual>
            </VisualBrush>
        </Grid.Background>
    </Grid>
</Window>

  在这里我们用到了VisualBrush这个画刷,然后再在VisualBrush的Visual中添加我们自定义的Style,这个是一个非常重要的画刷,如果我们对WPF的继承关系清楚的话,我们会发现几乎所有的控件都是从Visual这个顶级的基类继承过来的,所以几乎所有的Control都能够作为VisualBrush的Visual,所以Grid的Background属性是十分丰富的,这里我们定义了一个BackgroundPlayer的自定义控件,并且更改了其控件模板。

     那么我们再重点看一下这个自定义控件的后台是如何进行定义的:      

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace TestBackGroundWorker
{
  public class BackgroundPlayer : System.Windows.Controls.Control
  {
    static BackgroundPlayer()
    {
      DefaultStyleKeyProperty.OverrideMetadata(typeof(BackgroundPlayer), new FrameworkPropertyMetadata(typeof(BackgroundPlayer)));
    }

    public string Source
    {
      get { return (string)GetValue(SourceProperty); }
      set { SetValue(SourceProperty, value); }
    }
   
    public static readonly DependencyProperty SourceProperty =
      DependencyProperty.Register("Source", typeof(string), typeof(BackgroundPlayer), new FrameworkPropertyMetadata("", (a, b) =>
      {
        BackgroundPlayer bp = a as BackgroundPlayer;
        if (bp.Player != null)
        {
          bp.Player.Source = new Uri(b.NewValue.ToString().Replace("~", AppDomain.CurrentDomain.BaseDirectory), UriKind.RelativeOrAbsolute);
        }        
      }));

    private MediaElement _player;

    public MediaElement Player
    {
      get { return _player; }
      set { _player = value; }
    }

    public override void OnApplyTemplate()
    {
      Player = GetTemplateChild("Media") as MediaElement;
      if (null == Player)
        throw new ArgumentNullException("Media");

      Player.LoadedBehavior = MediaState.Manual;
      Player.MediaEnded += Player_MediaEnded;
      Player.MediaOpened += Player_MediaOpened;
      Player.MediaFailed += Player_MediaFailed;
      Player.Loaded += Player_Loaded;
      if (!string.IsNullOrEmpty(Source))
      {
        Player.Source = new Uri(Source.Replace("~", AppDomain.CurrentDomain.BaseDirectory), UriKind.RelativeOrAbsolute);
        Player.Play();
      }
      base.OnApplyTemplate();
    }

    void Player_Loaded(object sender, RoutedEventArgs e)
    {
    }

    void Player_MediaFailed(object sender, ExceptionRoutedEventArgs e)
    {
    }

    void Player_MediaOpened(object sender, RoutedEventArgs e)
    {
      //Player.Play();
    }

    void Player_MediaEnded(object sender, RoutedEventArgs e)
    {
      Player.Position = TimeSpan.FromMilliseconds(1);
      Player.Play();
    }

  }
}

  这里我们的自定义控件是从System.Windows.Controls.Control这里继承过来的,我们看一下相关的代码,然后做进一步的分析。首先我们必须为当前的类添加一个默认的静态构造函数,这个是非常重要的,它会更改默认的Control的样式。

static BackgroundPlayer()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(BackgroundPlayer), new FrameworkPropertyMetadata(typeof(BackgroundPlayer)));
        }

 接下来我们需要为自定义控件定义一些默认的依赖项属性,首先第一个是:Source属性,既然我们将Control的属性定义为MediaElement,那么我们一定要为这个MediaElement设置相关的属性,这里我们为这个Source属性定义了一个当属性变化时的回调函数,这个在xaml中第一次为Source属性赋值时就会触发该回调函数,所以我们经常可以利用该回调函数来做一些操作,这个回调函数是非常有用的。

     另外我们还需要为MediaElement设置一些常见的属性,比如说当前片源放完成后会后续进行什么操作等。

  这里我们是通过重载基类的OnApplyTemplate方法来进行相关的操作的,我们在了解WPF时必须懂得,去重载这些常见的虚方法来完成我们的操作。当然这也需要我们不断去积累。

      我们来看看OnApplyTemplate这个虚方法是为了完成什么样的操作,通过重写OnApplyTemplate()后就可以通过GetTemplateChild方法获取模板里的子控件了,但是OnApplyTemplate的执行顺序有问题,当类的构造函数执行后,并不是立即执行OnApplyTemplate方法,而是延迟了一定的时间,而且如果这个自定义的控件在放到应用的项目中时如果Visibility为隐藏的话,更是不会执行OnApplyTemplate方法了,这点需要我们去留心,在我们的程序中也是通过重写OnApplyTemplate方法来获取MediaElement对象,从而为其添加事件,这是一种非常有效果的方式。

      最后贴出相应的截图看看动画的效果(星空风格图)

以上就是c# WPF设置软件界面背景为MediaElement并播放视频的详细内容,更多关于c# WPF设置软件界面背景为MediaElement的资料请关注其它相关文章!

您可能感兴趣的文章:
  • C# 使用WPF 用MediaElement控件实现视频循环播放
  • 关于.NET/C#/WCF/WPF 打造IP网络智能视频监控系统的介绍
  • C# wpf 通过HwndHost渲染视频的实现方法

c# – MediaElement支持哪些格式?

c# – MediaElement支持哪些格式?

在C#中,MediaElement支持哪些格式?

解决方法

以下是MediaElement支持的格式编解码器的汇总列表.无论文件扩展名是什么,都支持这些编码.

资料来源:https://msdn.microsoft.com/en-us/library/cc189080(v=vs.95).aspx

>视频

>原始视频
> RGBA格式

>未压缩的32位Alpha红色,绿色,蓝色.
>在Windows Phone 7上,将忽略Alpha通道.

> YV12格式 – YCrCb(4:2:0)

>未压缩的YCrCb(4:2:0).
> Windows Phone 7不支持.

> RGBA – 32位Alpha红色,蓝色
> Windows Media Video和VC-1格式WMV1:Windows Media Video 7

>支持简单,主要和高级配置文件.
>仅支持渐进式(非隔行扫描)内容.

> WMV2:Windows Media Video 8
> WMV3:Windows Media Video 9

>支持简单和主要配置文件.
>仅支持渐进式(非隔行扫描)内容.

> WMVA:Windows Media Video Advanced Profile,非VC-1
> WVC1:Windows Media Video Advanced Profile,VC-1

>支持高级配置文件.
>仅支持渐进式(非隔行扫描)内容.

> H264(ITU-T H.264 / ISO MPEG-4 AVC)格式

>支持H.264和MP43编解码器.
>支持Base,Main和High Profiles.
> Windows Phone 7最高支持3.0级.
>请注意,级别3.0将30fps的最大支持分辨率定义为720×480.其他帧速率具有不同的最大支持分辨率.
>仅支持渐进式(非隔行扫描)内容.
>仅支持4:2:0色度子采样配置文件.
>桌面Silverlight仅支持附件B NAL格式(即起始码).
>注意,媒体库(例如SmoothStreamingMediaElement)通过以编程方式将AVC NAL转换为附件B NAL来支持AVC NAL格式.由于Silverlight支持对H.264样本进行部分加密,因此如果NAL标头未加密,则此转换也可以在加密内容上进行.附件B NAL格式在MPEG-4 Part 10中描述.
>支持带有Mp4的PlayReady DRM(H264和AAC-LC)

> H.263格式

>桌面版Silverlight不支持.
> Windows Phone 7中的mediastreamsource类不支持.

> MPEG-4第2部分格式

>支持简单和高级配置文件.

>音频

> PCM / WAV格式“1”.这是线性8位或16位脉冲编码调制.粗略地说,这是WAV格式.

>这是线性8位或16位脉冲编码调制.粗略地说,这是WAV格式.

> Microsoft Windows Media Audio标准格式.“353” – Microsoft Windows Media Audio v7,v8和v9.x标准格式(WMA标准版)
> Microsoft Windows Media Audio Professional格式.“354” – Microsoft Windows Media Audio v9.x和v10 Professional(WMA Professional)

>支持32-96 kbps范围内WMA 10专业低比特率(LBR)模式的完全保真解码.
>多声道(5.1和7.1环绕声)音频内容自动混合为立体声.
> 24位音频将返回静音.
>超过48000的采样率在同域中返回无效格式错误代码,在跨域方案中返回4001.

> MP3“85” – (ISO MPEG-1 Layer III)格式(MP3).
> AAC“255” – (ISO高级音频编码)(AAC)格式.

>支持完全保真度(高达48 kHz)的低复杂度(AAC-LC)解码.
>高效(HE-AAC)编码内容.将仅以半保真度(高达24 kHz)进行解码.

>支持HE-AAC v1(AAC)和HE-AAC v2(eAAC).
>桌面Silverlight只能以半保真度(最高24 kHz)进行解码.

>不支持多声道(5.1环绕声)音频内容.

> AMR-NB(自适应多速率窄带)格式

>桌面版Silverlight不支持.
> mediastreamsource类不支持.

>附加限制

>任何Silverlight平台都不支持以下编解码器格式:

> Windows Media Screen
> Windows Media Audio Professional无损
> Windows Media Voice

> Windows Phone 7不支持视频帧大小的动态更改

今天的关于使用MediaElement播放Stream中的视频如何使用mediaplayer播放视频的分享已经结束,谢谢您的关注,如果想了解更多关于android – 如何使用MediaCodec,MediaExtractor或MediaMetadataRetriever确定视频文件的帧速率?、Android多媒体之使用MediaExtractor与MediaMuxer分离音视频、c# WPF设置软件界面背景为MediaElement并播放视频、c# – MediaElement支持哪些格式?的相关知识,请在本站进行查询。

本文标签: