Я пишу код Java, чтобы взять видеофайл в формате mp4, применить к нему эффект, а затем сохранить его в новом файле.Код должен разбить данное видео на его кадры и сохранить их в массиве, чтобы каждый из них мог использовать их для создания эффекта.Эта часть кода обрабатывается xuggler, поэтому мне трудно определить, что происходит не так.
Проблема в том, что даже перед чтением одного изображения видео выдается ошибка, и я понятия не имею, чтоон имеет в виду, и обширный поиск в Google говорит мне, что это как-то связано с ошибкой доступа к памяти.
Еще более странная часть заключается в том, что это происходит только для некоторых файлов mp4, даже если они все в формате mp4 и должны все вести себятаким же образом.
Я пробовал много разных файлов mp4 из разных источников, и некоторые из них работают, некоторые нет, на первый взгляд, наугад.Mp4, к которому меня больше всего интересует применение эффекта, - это один из тех, которые не работают.
В следующем коде я определил с помощью операторов print в различных точках, что часть кодаошибка возникает где-то внутри IMediaListener с именем переменной media.Сам слушатель вызывается линией while(reader.readPacket()==null);
внутри ActionListener, в частности, в разделе, вызванном нажатием кнопки «sub».Это единственное место, где он называется.
Я должен отметить, что весь код, связанный с xuggler, не мой, как я нашел его в демонстрациях кода в Интернете.Я не буду притворяться, что понимаю, как работает xuggler.
import java.util.*;
import java.util.concurrent.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.*;
import java.awt.image.*;
import com.xuggle.xuggler.*;
import com.xuggle.mediatool.*;
import com.xuggle.mediatool.event.*;
import java.awt.event.*;
public class mainClass {
static JFrame win=new JFrame();
static JPanel dis=new JPanel();
static JButton sub=new JButton("Submit"),b1=new JButton("Browse"),b2=new JButton("Browse");
static JTextField input=new JTextField(),output=new JTextField();
static String savePath="",sourcePath="";
static JLabel l1=new JLabel("Input:"),l2=new JLabel("Output:");
static BufferedImage[] images=new BufferedImage[0];
static Set<Long> timestamps=new HashSet<Long>();
static int ind=0;
public static void main(String[]args) {
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setResizable(false);
win.setVisible(true);
win.add(dis);
win.setLocation(100,300);
dis.setPreferredSize(new Dimension(850,80));
dis.setLayout(null);
win.pack();
dis.add(input).setBounds(100,0,550,40);
dis.add(output).setBounds(100,40,550,40);
dis.add(sub).setBounds(750,0,100,80);
dis.add(b1).setBounds(650,0,100,40);
dis.add(b2).setBounds(650,40,100,40);
dis.add(l1).setBounds(0,0,100,40);
dis.add(l2).setBounds(0,40,100,40);
input.setFocusable(false);
input.setFont(new Font(Font.SANS_SERIF,Font.PLAIN,22));
output.setFocusable(false);
output.setFont(input.getFont());
sub.setFocusable(false);
sub.addActionListener(action);
b1.setFocusable(false);
b1.addActionListener(action);
b2.setFocusable(false);
b2.addActionListener(action);
l1.setFont(input.getFont());
l1.setHorizontalAlignment(SwingConstants.CENTER);
l2.setFont(input.getFont());
l2.setHorizontalAlignment(SwingConstants.CENTER);
}
static IMediaListener media=new MediaListenerAdapter() {
public void onVideoPicture(IVideoPictureEvent e) {
timestamps.add(e.getTimeStamp(TimeUnit.MICROSECONDS));
BufferedImage image=e.getImage();
BufferedImage[] copy=images;
images=new BufferedImage[copy.length+1];
for(int i=0;i<copy.length;i++) {
images[i]=copy[i];
}
images[images.length-1]=image;
}
};
static ActionListener action=new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(e.getSource()==sub) {
if(input.getText().length()>0&output.getText().length()>0) {
IMediaReader reader=ToolFactory.makeReader(input.getText());
reader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
reader.addListener(media);
while(reader.readPacket()==null);
BufferedImage[] pics=images;
Long[] times=new Long[timestamps.size()];
times=timestamps.toArray(times);
for(int i=0;i<pics.length;i++) {
int min=i;
for(int j=i;j<pics.length;j++) {
if(times[j]<times[min]) {
min=j;
}
}
Long f1=times[i];
times[i]=times[min];
times[min]=f1;
}
timestamps=new HashSet<Long>();
long frameSep=(long)(times[times.length-1]/times.length);
IMediaWriter writer=ToolFactory.makeWriter(output.getText()+"\\video1.mp4");
writer.addVideoStream(0,0,ICodec.ID.CODEC_ID_MPEG4,pics[0].getWidth(),pics[0].getHeight());
for(int i=0;i<pics.length+pics[0].getHeight()-1;i++) {
BufferedImage image=pics[0];
for(int j=0;j<i;j++) {
int ind=i-j,ind2=image.getHeight()-j-1;
if(ind>=pics.length) {
ind=pics.length-1;
}
if(ind2<0) {
ind2=0;
}
int[] rgbArray=new int[image.getWidth()];
pics[ind].getRGB(0, ind2, image.getWidth(), 1, rgbArray, 0, image.getWidth());
image.setRGB(0, ind2, image.getWidth(), 1, rgbArray, 0, image.getWidth());
}
writer.encodeVideo(0, image, frameSep*i, TimeUnit.MICROSECONDS);
if(i%((pics.length+pics[0].getHeight()-1)/100)==0) {
System.out.println(Double.toString(i/(pics.length+pics[0].getHeight()-1)*100)+" %");
}
}
System.out.println("finished");
writer.close();
}
}
if(e.getSource()==b1) {
JFileChooser fc=new JFileChooser();
fc.setMultiSelectionEnabled(false);
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
fc.setFileFilter(new FileNameExtensionFilter("mp4 file","mp4"));
fc.setAcceptAllFileFilterUsed(false);
if(fc.showOpenDialog(sub)==JFileChooser.APPROVE_OPTION)input.setText(fc.getSelectedFile().getAbsolutePath());
}
if(e.getSource()==b2) {
JFileChooser fc=new JFileChooser();
fc.setMultiSelectionEnabled(false);
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if(fc.showOpenDialog(sub)==JFileChooser.APPROVE_OPTION)output.setText(fc.getSelectedFile().getAbsolutePath());
}
}
};
}
Для данного mp4, который работает, код завершит применение эффекта, а затем напечатает «Finish», так что я знаю, чтобы пойти и проверить выводпапка, которая может быть указана в графическом интерфейсе, который первоначально появляется.
Для данного mp4, который не работает, в консоль выводится следующее сообщение об ошибке, в точности так:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000006ee76520, pid=2176, tid=0x00000000000000c0
#
# JRE version: Java(TM) SE Runtime Environment (8.0_211-b12) (build 1.8.0_211-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.211-b12 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [xuggle1222138188201648765.dll+0x736520]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\John\eclipse-workspace\Video effects\hs_err_pid2176.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
файл журнала, на который он ссылается, содержит массу сложной информации, которую я не могу понять, говоря о расположении регистров, о виртуальных машинах и т. Д., О которой я не буду претендовать на понимание.
Любая помощь чрезвычайно ценится!