C# 做一个播放音频文件的进度条该怎么实现呢??

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 做一个播放音频文件的进度条该怎么实现呢??相关的知识,希望对你有一定的参考价值。

当点击播放的时候根据音频文件的时间动态显示进度,用TrackBar不知道可不可以,有没高手给个详细的代码实现,万分感谢...

没办法,几乎所有的timer有会有一定的时间误差。不过听你的意思貌似是根据timer的计算来更新进度条的数据??
你可以在timer里执行这个操作:
获取音频文件当前的播放位置[如果用windowmediaplayer的话,这个位置将会是时间,不是的话应该是流位置],根据这个重新更新进度条
参考技术A 先读取视频的总时间,之后 获取现在已播放时间比上总时间, 得到一个百分比, 再用两个div背景设置就可以做成进度条了。 拖拉也可以的。 比较吃js功夫的。
音频格式是指要在计算机内播放或是处理音频文件,是对声音文件进行数、模转换的过程。音频格式最大带宽是20KHZ,速率介于40~50KHZ之间,采用线性脉冲编码调制PCM,每一量化步长都具有相等的长度。
参考技术B   实现的代码为:
  private void GetData()

string strConn = "Data Source=.;Initial Catalog=dbXXX;User ID=sa;pwd=123456";
SqlConnection con = new SqlConnection(strConn);
SqlDataAdapter da = new SqlDataAdapter("select * from tableX", con);
DataSet ds = new DataSet();
da.Fill(ds);
int count = ds.Tables[0].Rows.Count;
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;
progressBar1.BackColor = Color.Green;
for (int i = 0; i < count; i++) //为了能看出效果 用for循环来减低速度

for (int j = 0; j < 1000; j++)

if (Convert.ToInt32(ds.Tables[0].Rows[i]["***"].ToString()) > 20)
cc++;

progressBar1.Value = ((i + 1) * 100 / count);

dataGridView1.DataSource = ds.Tables[0];
参考技术C progressBar1.Maximum = (int)axWindowsMediaPlayer1.currentMedia.duration;
progressBar1.Minimum = 0;
progressBar1.Step = (int)(progressBar1.Maximum / 20);
progressBar1.Value = (int)axWindowsMediaPlayer1.Ctlcontrols.currentPosition;
time.Text = axWindowsMediaPlayer1.Ctlcontrols.currentPositionString;

放在Timer里.本回答被提问者采纳

如何使用音频文件作为进度条更新 jslider

【中文标题】如何使用音频文件作为进度条更新 jslider【英文标题】:How to update jslider with an audio file as progress bar 【发布时间】:2013-04-06 20:15:01 【问题描述】:

我有一个 wav 音频文件。我知道如何在 java 中使用 AudioImputStream 播放它。我学会了创建一个jslider。现在我必须将滑块用作音频的进度条,例如音频播放,因此滑块向前移动。如果用户改变了滑块的位置,音频文件必须从那个位置开始播放。

我是 Java 新手,我可能在帖子中犯了一些错误。请忽略它们

所以当滑块更新时,我一直在更新音轨。我尝试将 changeListner 添加到滑块,但无法正常工作。

这是代码

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class audio 

public static void main(String args[])


try 
final JFrame f=new JFrame();
File yourFile;
AudioInputStream stream;
AudioFormat format;
DataLine.Info info;
final Clip clip;
yourFile = new File(fileName);

stream = AudioSystem.getAudioInputStream(yourFile);
format = stream.getFormat();
final long frames =stream.getFrameLength();
final double durationInSeconds = (frames+0.0) / format.getFrameRate();  
final JSlider slider=new JSlider(0,(int) Math.round(durationInSeconds),0);
info = new DataLine.Info(Clip.class, format);
clip = (Clip) AudioSystem.getLine(info);
clip.open(stream);
clip.start();

f.add(slider);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
TimerTask timerTask=new TimerTask()

@Override
public void run() 
// TODO Auto-generated method stub

double timeNow=(durationInSeconds*clip.getFramePosition())/frames;
slider.setValue((int)Math.round(timeNow));
f.repaint();



;
Timer timer = new Timer("MyTimer");//create a new Timer

timer.scheduleAtFixedRate(timerTask, 30, 30);//this line starts the timer at the same time its executed




catch (Exception e) 
System.out.println(e);





【问题讨论】:

您至少尝试过什么吗?如果是这样,请在此处发布您的代码,以便对其进行改进。我们不会为您完成所有的工作。 我不知道你到目前为止有什么,但我会假设你正在使用 DataLine 而不是 Clip 在线程中播放音频。从那里开始它的简单数学。您从 0% 开始,声音文件的结尾是 100%。找到音频文件的长度,然后在音频文件播放时跟踪您在音频文件中的距离,并从线程中相应地调整滑块。我相信它会类似于 currentPositionInTrack / totalLengthOfTrack * 100,希望我没有错,但这应该会给你完成的百分比。如果您需要更多帮助,则必须更具体。 这样更新滑块的问题就解决了。我使用了一个计时器,在其中我获取当前音轨帧,将其转换为持续时间并每 30 毫秒更新一次计时器。 但我仍然坚持如何更新滑块更新中的轨道。 【参考方案1】:

这样更新滑块的问题就解决了。我使用了一个计时器,在其中我获取当前音轨帧,将其转换为持续时间并每 30 毫秒更新一次计时器。

但我仍然坚持如何更新滑块更新中的轨道。

我不明白您为什么要手动更新轨道:如果您已经可以获取音轨的当前帧,则它必须正在更新。因此,要解决您可能面临的问题:

如果您的滑块没有正确更新,我发现将其从组件中删除然后更新它,然后重新添加它以工作:

@Override
public void run() 
// TODO Auto-generated method stub

f.remove(slider);
double timeNow=(durationInSeconds*clip.getFramePosition())/frames;
slider.setValue((int)Math.round(timeNow));
f.add(slider);
f.repaint();

如果您想手动更新剪辑,请使用clip.setFramePosition(int frames)

【讨论】:

【参考方案2】:

我在运行您的代码时观察到的情况如下:JSlider 确实会更新,但每秒只有一次(或稍快)。

我不知道这是否是答案,但也许值得考虑。有时重绘的调用会“崩溃”。可能是 EDT 没有对每个重绘调用做出反应,而是决定相邻的调用足够相似,以至于它们可以折叠成更少的重绘。我注意到,如果我在 TimerTask 中放置一个 System.out.println(timeNow),每秒在控制台上打印大约 33 个 timeNow,我认为这是您希望 JSlider 更新的速率。

我发现,如果我在单独的类中有一个 Timer(连同它的 TimerTask)并从那里调用重绘,则 EDT 折叠重绘的可能性会更小。我记得有一次在 JPanel 上放置 Timer 之前,将它称为“它自己的”重绘给了我类似的“折叠 EDT”结果。

我不知道这背后的确切机制或理论。所以这可能不是最好的建议。但是仍然值得将计时器代码分离到自己的类中。为此,您还必须将 JFrame 和 Clip 的副本传递给此类。

【讨论】:

以上是关于C# 做一个播放音频文件的进度条该怎么实现呢??的主要内容,如果未能解决你的问题,请参考以下文章

ios音频:使用audioqueue改变播放进度

【Android音视频】视频开发优化

java js前端请求后台去获得音频流,然后播放音乐,音乐可以控制进度,显示总时长

Android 音频播放——AudioTrack直接播PCMMediaPlayer播媒体文件可以是audio

OpenCV中如何播放avi文件的音频

Android在音频播放器中刷新Seekbar进度和播放持续时间导致音频播放滞后