我正在构建一个JavaFx应用程序,其中我有一个文本文件和一个读取它的音频mp3文件。当我使用MediaPlayer对象播放音频并显示文本文件中的文本时。是否有任何方法可以突出显示每个单词?我知道字幕是如何编码并保存在一个单独的文件中的,但是这里必须为每个单词完成。即文本文件中的每个单词都应该包含元数据应该保持多长时间,从mp3文件的开头偏移突出显示。
另一种方法是使用公式和文本和音频文件的长度进行计算,并查找每个世界应该保持突出显示的大致时间,但此凸轮使突出显示不同步。
是否有任何标准方式或标准元数据格式,我可以在其中编码信息在叙述音频播放时应突出显示多少时间?
答案 0 :(得分:0)
我使用直接逻辑。这个东西不能自动(可以,但需要无穷无尽的努力),所以首先你需要让用户设置时间。显示.txt文件,然后在后台播放歌曲。在此帮助下,用户突出显示单词,现在您可以在System.Current时间的帮助下以毫秒为单位获取计时,并将计时存储在数组或列表中。完成后,现在你玩卡拉OK。按照时间突出显示单词。按ESC键可以突出显示单词。根据需要更改.txt文件。 请忽略我糟糕的编码风格:p
以下是Swing中的演示:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.GroupLayout.*;
public class newh extends JFrame
implements DocumentListener {
public static int[] arry=new int[1000];
static int first=0,last=0,scan=0,acount=0;int flag=1,point=0,j=0;long value,stat;
private JTextField entry;private boolean fir=true;
private JLabel jLabel1;
private JScrollPane jScrollPane1;
private JLabel status;
private JTextArea textArea;
private JFrame frame;
long start;
final static Color HILIT_COLOR = Color.YELLOW;
final static Color ERROR_COLOR = Color.PINK;
final static String CANCEL_ACTION = "cancel-search";
final static String SMALL_ICON = "cancel-search";
final Color entryBg;
final Highlighter hilit;
final Highlighter.HighlightPainter painter;
private long start2;
JButton startButton;
public newh() throws FileNotFoundException {
initComponents();
String[] a=new String[1000];
InputStream in = getClass().getResourceAsStream("lyri.txt");
try {
textArea.read(new InputStreamReader(in), null);
} catch (IOException e) {
e.printStackTrace();
}
hilit = new DefaultHighlighter();
painter = new DefaultHighlighter.DefaultHighlightPainter(HILIT_COLOR);
textArea.setHighlighter(hilit);
entryBg = entry.getBackground();
entry.getDocument().addDocumentListener(this);
InputMap im = entry.getInputMap(JComponent.WHEN_FOCUSED);
ActionMap am = entry.getActionMap();
im.put(KeyStroke.getKeyStroke("ESCAPE"), CANCEL_ACTION);
am.put(CANCEL_ACTION, new CancelAction());
}
/** This method is called from within the constructor to
* initialize the form.
*/
private void initComponents() {
entry = new JTextField();
textArea = new JTextArea();
textArea.setBackground(Color.ORANGE);
status = new JLabel();
jLabel1 = new JLabel();
frame = new JFrame();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setTitle("TextFieldDemo");
textArea.setColumns(20);
textArea.setLineWrap(true);
textArea.setRows(5);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
jScrollPane1 = new JScrollPane(textArea);
final JFrame jar=new JFrame();
jLabel1.setText("Enter text to search:");
startButton = new JButton("Start");jar.add(startButton);
jar.setVisible(true);jar.pack();
startButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
try {
ColoredTextTest.start();
} catch (InterruptedException ex) {
Logger.getLogger(newh.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(newh.class.getName()).log(Level.SEVERE, null, ex);
}
setVisible(false);
jar.setVisible(false);
}
});
GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
//Create a parallel group for the horizontal axis
ParallelGroup hGroup = layout.createParallelGroup(GroupLayout.Alignment.LEADING);
//Create a sequential and a parallel groups
SequentialGroup h1 = layout.createSequentialGroup();
ParallelGroup h2 = layout.createParallelGroup(GroupLayout.Alignment.CENTER);
//Add a container gap to the sequential group h1
h1.addContainerGap();
//Add a scroll pane and a label to the parallel group h2
h2.addComponent(jScrollPane1, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 600, Short.MAX_VALUE);
h2.addComponent(status, GroupLayout.Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 900, Short.MAX_VALUE);
//Create a sequential group h3
SequentialGroup h3 = layout.createSequentialGroup();
h3.addComponent(jLabel1);
h3.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED);
h3.addComponent(entry, GroupLayout.DEFAULT_SIZE, 900, Short.MAX_VALUE);
//Add the group h3 to the group h2
h2.addGroup(h3);
//Add the group h2 to the group h1
h1.addGroup(h2);
h1.addContainerGap();
//Add the group h1 to the hGroup
hGroup.addGroup(GroupLayout.Alignment.TRAILING, h1);
//Create the horizontal group
layout.setHorizontalGroup(hGroup);
//Create a parallel group for the vertical axis
ParallelGroup vGroup = layout.createParallelGroup(GroupLayout.Alignment.LEADING);
//Create a sequential group v1
SequentialGroup v1 = layout.createSequentialGroup();
//Add a container gap to the sequential group v1
v1.addContainerGap();
//Create a parallel group v2
ParallelGroup v2 = layout.createParallelGroup(GroupLayout.Alignment.BASELINE);
v2.addComponent(jLabel1);
v2.addComponent(entry, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE);
//Add the group v2 tp the group v1
v1.addGroup(v2);
v1.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED);
v1.addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 900, Short.MAX_VALUE);
v1.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED);
v1.addComponent(status);
v1.addContainerGap();
//Add the group v1 to the group vGroup
vGroup.addGroup(v1);
layout.setVerticalGroup(vGroup);
pack();
}
@SuppressWarnings("empty-statement")
public void search() throws BadLocationException {
int i;
start=System.currentTimeMillis();
arry[point]=(int) (start - start2-10);
point++;
if(fir==true)
{fir=false;point=0;}
start2=start;
String s = textArea.getText();
char[] words=s.toCharArray();
for(i=last;words[i]!=' '&&words[i]!='\n';i++,last=i)
{
}
try {
hilit.addHighlight(first, last, painter);
last++; first=last;
} catch (BadLocationException ex) {
Logger.getLogger(newh.class.getName()).log(Level.SEVERE, null, ex);
}
}
void message(String msg) {
}
// DocumentListener methods
public void insertUpdate(DocumentEvent ev) {
// search();
}
public void removeUpdate(DocumentEvent ev) {
// search();
}
public void changedUpdate(DocumentEvent ev) {
}
public void keyTyped(KeyEvent e) throws BadLocationException {
}
public void keyReleased(KeyEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
class CancelAction extends AbstractAction {
public void actionPerformed(ActionEvent ev) {
try {
search();
} catch (BadLocationException ex) {
Logger.getLogger(newh.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[]) throws UnsupportedAudioFileException, IOException, LineUnavailableException, InterruptedException {
start();
}
public void setvisiblet()
{
setVisible(true);
}
public void setvisiblef()
{
setVisible(false);
}
public static void start()
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
UIManager.put("swing.boldMetal", Boolean.FALSE);
try {
new newh().setVisible(true);
} catch (FileNotFoundException ex) {
Logger.getLogger(newh.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
}
class ColoredTextTest extends javax.swing.JFrame {
private String[] words=new String[1000];
private JScrollPane sc;
String sentence="";
int stringIndex = 0;
int index = 0;
Timer timer;
StyledDocument doc;
/** Creates new form textdisplay */
@SuppressWarnings("static-access")
public ColoredTextTest() throws FileNotFoundException, IOException {
initComponents();
doc = new DefaultStyledDocument();
jTextPane1.setDocument(doc);
javax.swing.text.Style style = jTextPane1.addStyle("Red", null);
StyleConstants.setForeground(style, Color.RED);
File file = new File("lyri.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
while( (line = br.readLine())!= null ){
sentence+=line;
sentence+='\n';
}
br.close();
int j=0;
Scanner input = new Scanner(new File("lyri.txt"));
file = new File("lyri.txt");
br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
while(input.hasNext()) {
words[j] = input.next(); System.out.println(words[j]);j++;words[j]=" ";j++;
}
jTextPane1.setText(sentence);
}
@SuppressWarnings("unchecked")
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jButton3 = new javax.swing.JButton();
jButton4 = new javax.swing.JButton();
jSeparator1 = new javax.swing.JSeparator();
jScrollPane1 = new javax.swing.JScrollPane();
jTextPane1 = new javax.swing.JTextPane();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setBackground(new java.awt.Color(0, 0, 0));
setUndecorated(true);
jPanel1.setBackground(new java.awt.Color(0, 0, 0));
jPanel1.setBorder(javax.swing.BorderFactory.createMatteBorder(3, 3, 3, 3, new java.awt.Color(0, 204, 204)));
jPanel1.setInheritsPopupMenu(true);
jButton1.setBackground(new java.awt.Color(255, 255, 0));
jButton1.setFont(new java.awt.Font("Virtual DJ", 0, 14));
jButton1.setForeground(new java.awt.Color(0, 255, 255));
jButton1.setText("Back");
jButton1.setOpaque(false);
jButton2.setBackground(new java.awt.Color(255, 255, 0));
jButton2.setFont(new java.awt.Font("Virtual DJ", 0, 14));
jButton2.setForeground(new java.awt.Color(0, 255, 255));
jButton2.setText("Pause");
jButton2.setOpaque(false);
jButton3.setBackground(new java.awt.Color(255, 255, 0));
jButton3.setFont(new java.awt.Font("Virtual DJ", 1, 14));
jButton3.setForeground(new java.awt.Color(0, 255, 255));
jButton3.setText("Play");
jButton3.setOpaque(false);
jButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton3ActionPerformed(evt);
}
});
jButton4.setBackground(new java.awt.Color(255, 255, 0));
jButton4.setFont(new java.awt.Font("Virtual DJ", 0, 14));
jButton4.setForeground(new java.awt.Color(0, 255, 255));
jButton4.setText("close");
jButton4.setOpaque(false);
jButton4.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton4ActionPerformed(evt);
}
});
jSeparator1.setBackground(new java.awt.Color(51, 255, 255));
jTextPane1.setBackground(new java.awt.Color(0, 0, 0));
jTextPane1.setFont(new java.awt.Font("Tahoma", 0, 36)); // NOI18N
jTextPane1.setForeground(new java.awt.Color(0, 255, 255));
jTextPane1.setVerifyInputWhenFocusTarget(false);
jScrollPane1.setViewportView(jTextPane1);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton4, javax.swing.GroupLayout.DEFAULT_SIZE, 611, Short.MAX_VALUE)
.addGap(23, 23, 23))
.addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 982, Short.MAX_VALUE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 982, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 645, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jButton4, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
setBounds((screenSize.width-988)/2, (screenSize.height-710)/2, 988, 710);
}// </editor-fold>
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
setVisible(false);
}
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
this.sc=jScrollPane1;
JScrollBar verticalScrollBar = sc.getVerticalScrollBar();
JScrollBar horizontalScrollBar = sc.getHorizontalScrollBar();
verticalScrollBar.setValue(verticalScrollBar.getMinimum());
horizontalScrollBar.setValue(horizontalScrollBar.getMinimum());
dotimer();
}
public void dotimer()
{
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("index"+stringIndex);
doc.setCharacterAttributes(stringIndex, 1, jTextPane1.getStyle("Red"), true);
stringIndex++;
try {
if (stringIndex >= doc.getLength() || doc.getText(stringIndex, 1).equals(" ")|| doc.getText(stringIndex, 1).equals("\n")) {
index++;
}
} catch (BadLocationException ex) {
Logger.getLogger(ColoredTextTest.class.getName()).log(Level.SEVERE, null, ex);
}
if (index < 600) {
double delay = newh.arry[index];
timer.setDelay((int) (delay / words[index].length()));
} else {
timer.stop();
System.err.println("Timer stopped");
}
}
};
timer = new Timer(newh.arry[index], actionListener);
timer.setInitialDelay(0); System.out.println("done.........");
timer.start();
}
public static void main(String args[]) throws InterruptedException, InvocationTargetException {
start();
}
public static void start() throws InterruptedException, InvocationTargetException
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new ColoredTextTest().setVisible(true);
} catch (FileNotFoundException ex) {
Logger.getLogger(ColoredTextTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ColoredTextTest.class.getName()).log(Level.SEVERE, null, ex);
}
ColoredTextTest y = null;
try {
y = new ColoredTextTest();
} catch (FileNotFoundException ex) {
Logger.getLogger(ColoredTextTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ColoredTextTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JButton jButton4;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JTextPane jTextPane1;
}