الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

مشكلة في إدراج الصور و الملفات الصوتية

بدأه khaled_prg في 24 أكتوبر 2012 · 32 رد · 1,915 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

قمتُ بكتابة برنامج صغير (للتدرب) يحتوي على صورتين و ملف صوتي يتم تشغيله أثناء عمل البرنامج.

البرنامج يعمل 100% عند تشغيله من NetBeans ..

لكن عندما أنقل ملف الجار إلى حاسوب آخر و أقوم بتشغيله لا تظهر الصور و لا يتم تشغيل الملف الصوتي أيضاً !

السؤال : كيف أضمن تشغيل الصور و الملفات الصوتية في أي حاسوب ؟

شكراً مقدماً.

#2

افتح ملف الجار بواسطة برنامج winrar او winzip

وتاكد من وجود الصوره في ملف الجار !

#3

بالاضافة الى ما ذكره الاخ العيافي يجب ان تتأكد من انك تقوم بقراءة ملف الــ Jar من المسار الذي يشغل منه الملف حيث ان النت بينز يقوم بتغيير مسار تشغيل الملف

final File currentJar = new File(YourClassName.class.getProtectionDomain().getCodeSource().getLocation().toURI());

تم تعديل هذه المشاركة بواسطة mental-driller في 24 أكتوبر 2012 في 22:11

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#4

صرت أفرح كثييييير لما أجد مواضيع الك اخوي خالد في قسم الجافا ذلك لأني كلما الا وأتعلم منك شي جديد

موفق

556891961.gif

I am learning from you

it is the programmer eye

#5
اقتباس
افتح ملف الجار بواسطة برنامج winrar او winzip وتاكد من وجود الصوره في ملف الجار !

فتحت الجار ووجدت الصور و الملف الصوتي بداخله.

لكنني لاحظتُ أنه عندما أضع ملف الجار في جهة و أغير مسار ملف المشروع, لا تظهر الصور و الملف الصوتي أيضا لا يعمل ..

مالحل ؟

اقتباس
يجب ان تتأكد من انك تقوم بقراءة ملف الــ Jar من المسار الذي يشغل منه الملف حيث ان النت بينز يقوم بتغيير مسار تشغيل الملف

أنا وضعتُ الــ Absolute Path لملفات الميديا خشية أن أقع في المشاكل التي تتعلق بمسار الملفات ..

هل هذا ما تقصده ؟

اقتباس
صرت أفرح كثييييير لما أجد مواضيع الك اخوي خالد في قسم الجافا ذلك لأني كلما الا وأتعلم منك شي جديد

موفق

شكراً أخي مشاكس :)

#6

لا ليس تماما ، مادام انك بتضع المسار الكامل فيجب ان لاتكون هذه مشكله، ولكن اذا قمت بنقل الملفات الى جهاز الاخر واختلف المسار فان ملفاتك ببساطه تعتبر غير موجوده ، لذا يتم تحزيم هذه الملفات داخل ملف الجار.

قصدي هو ان الــ current directory تتغير حسب المكان الذي تشغل منه الملف وانت يجب عليك ان تشير الى الملف حسب مكانه في شجرة ملف الجار، ولذا فإن العنونه تفضل ان تكون relative اذا وجدت ان لديك مشكله تشغيل الملف ، تاكد من مكان تشغيل ملفك اي قم مثلا بطباعة المكان الذي يتم تشغيل ملف الجار منه باستخدام JOptionPane وقم بالاشارة الى الملفات حسب تدرجها من العنوان الذي يتم التنفيذ منه

كما يمكنك ان تستخدم الطريقه التي وضحتها لك في الاعلى حيث تقوم بالحصول على مكان ملف الجار ومنه تقوم باشتقاق مكان ملفات الميديا

اتمنى ان يكون هذا الشرح اوضح ، تحياتي

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#7

أشكرك أخي الكريم على سرعة الرد و متابعة الموضوع, جزاك الله خيراً :)

اقتباس
مادام انك بتضع المسار الكامل فيجب ان لاتكون هذه مشكله، ولكن اذا قمت بنقل الملفات الى جهاز الاخر واختلف المسار فان ملفاتك ببساطه تعتبر غير موجوده ، لذا يتم تحزيم هذه الملفات داخل ملف الجار.

قصدي هو ان الــ current directory تتغير حسب المكان الذي تشغل منه الملف وانت يجب عليك ان تشير الى الملف حسب مكانه في شجرة ملف الجار، ولذا فإن العنونه تفضل ان تكون relative اذا وجدت ان لديك مشكله تشغيل الملف ، تاكد من مكان تشغيل ملفك اي قم مثلا بطباعة المكان الذي يتم تشغيل ملف الجار منه باستخدام JOptionPane وقم بالاشارة الى الملفات حسب تدرجها من العنوان الذي يتم التنفيذ منه

الفكرة اتضحت لي و الحمد لله لكن أجد صعوبة في تطبيقها ..

اقتباس
كما يمكنك ان تستخدم الطريقه التي وضحتها لك في الاعلى حيث تقوم بالحصول على مكان ملف الجار ومنه تقوم باشتقاق مكان ملفات الميديا

أين أضع ذلك السطر ؟

هل لي بمثال لو سمحت ؟

#8

هذا كود بسيط قمت بكتابتة كمثال

final File currentJar = new File(NewClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
        System.out.println(currentJar.toPath());
        JOptionPane.showMessageDialog(null, currentJar.toString());
        ImageIcon img = new ImageIcon(currentJar.toString()+"\\MyImage.jpg");
        JFrame frame = new JFrame();
        JLabel label = new JLabel(img);
        frame.add(label);
        frame.setVisible(true);

تحياتي

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#9

قمتُ بتشغيل الكود و ظهر لي المسار التالي :

C:\Users\khaled\Documents\NetBeansProjects\NewProject\build\classes

و بطبيعة الحال لا يُمكنني أن أضع ملفات الميديا في المسار السابق لأنه عند عمل Clean and Build (من أجل تحديث ملف الجار) سيتم حذف جميع الملفات ..

ملاحظة : الدالة toPath غير موجودة في الفئة File لذا قمتُ باستبدالها بــ toURI.

#10

هذه ليست بمشكله قم باستخدام \.. لكي تصعد الى اعلى شجرة العنوان

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#11

حسب ما فهمت من الكود فإن الملف يتم تشغيله من مجلد الـ classes, صح ؟

اقتباس
هذه ليست بمشكله قم باستخدام \.. لكي تصعد الى اعلى شجرة العنوان

مالفائدة من الصعود إلى أعلى الشجرة إذا تم تنظيف مجلد الــ classes (هذا يعني حذف جميع ملفات الميديا) ؟ : (

#12

حسنا كل ما عليك فعله هو:

            Icon img = new ImageIcon(NewClass.class.getClass().getResource("/yourimage.jpg"));
            JFrame frame = new JFrame();
            JLabel label = new JLabel(img);
            frame.add(label);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

طبعا بفرض ان الصورة ليست داخل مجلد فرعي و الا قم باضافة اسم المجلد قبل اسم الصورة

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#13

قمتُ بكتابة الكود على هذا الشكل :

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class Fenetre extends JFrame {

    public Fenetre() {
        Icon img = new ImageIcon(Class.class.getClass().getResource("/yourimage.jpg"));
        JFrame frame = new JFrame();
        JLabel label = new JLabel(img);
        frame.add(label);
        frame.setTitle("Fenêtre java");
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(String agr[]) {
        Fenetre test = new Fenetre();
    }
}

لكن عند التشغيل أحصل على استثناء من نوع NullPointerException ..

#14

هل من الممكن ان تعطيني مخطط لشجرة الملفات، يعني هل الصورة توجد رأسا داخل مجلد المشروع؟

لمعرفة ذلك قم بفتح مجلد src وانظر داخله فاذا كانت الصورة موجوده مباشره داخل المجلد src فالطريقة التي في الاعلى يجب ان تنفع اما اذا كان موجود داخل مجلد اخر و لنقل src/images فعليك ان تقول

"/images/myimage.jpg"

تم تعديل هذه المشاركة بواسطة mental-driller في 25 أكتوبر 2012 في 23:29

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#15

هذه شجرة الملفات عندي :

----manifest.mf

----src

-------img1.jpg

-------img2.png

-------sound1.wav

----dist

----build

الصور أصبحت تظهر في الــ JFrame بشكل جيد و الحمد لله :)

لكن الملف الصوتي لا يتم تشغيله, لا أدري لماذا ! : (

هذه هي الفئة المسؤولة عن تشغيل الصوت :

import java.io.File;
import java.io.IOException;
import javax.sound.sampled.*;

public class AePlayWave extends Thread {

    private String filename;
    private Position curPosition;
    private final int EXTERNAL_BUFFER_SIZE = 524288; // 128Kb

    enum Position {

        LEFT, RIGHT, NORMAL
    };

    public AePlayWave(String wavfile) {
        filename = wavfile;
        curPosition = Position.NORMAL;
    }

    public void run() {
        File soundFile = new File(filename);
        if (!soundFile.exists()) {
            System.err.println("Wave file not found: " + filename);
            return;
        }

        AudioInputStream audioInputStream = null;
        try {
            audioInputStream = AudioSystem.getAudioInputStream(soundFile);
        } catch (UnsupportedAudioFileException e1) {
            e1.printStackTrace();
            return;
        } catch (IOException e1) {
            e1.printStackTrace();
            return;
        }

        AudioFormat format = audioInputStream.getFormat();
        SourceDataLine auline = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

        try {
            auline = (SourceDataLine) AudioSystem.getLine(info);
            auline.open(format);
        } catch (LineUnavailableException e) {
            e.printStackTrace();
            return;
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        if (auline.isControlSupported(FloatControl.Type.PAN)) {
            FloatControl pan = (FloatControl) auline.getControl(FloatControl.Type.PAN);
            if (curPosition == Position.RIGHT) {
                pan.setValue(1.0f);
            } else if (curPosition == Position.LEFT) {
                pan.setValue(-1.0f);
            }
        }

        auline.start();
        int nBytesRead = 0;
        byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];

        try {
            while (nBytesRead != -1) {
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0) {
                    auline.write(abData, 0, nBytesRead);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return;
        } finally {
            auline.drain();
            auline.close();
        }
    }
}

و الاستدعاء يكون هكذا :

String url = Class.class.getClass().getResource("/sound1.wav").toString();
Thread playWave = new AePlayWave(url);
playWave.start();

الخطأ الذي يظهر لي هو :

Wave file not found: file:/C:/Users/khaled/Documents/NetBeansProjects/newProject/build/classes/sound1.wav

#16

قم بالتشغيل من ملف الجار وليس من النت بينز ، قم بعرض الاخطاء باستخدام JOptionPane وليس باستخدام System.out.println لانك عندما تضغط على ملف الجار مرتين لن تظهر لك الاخطأ التي يتم طباعتها على الكونسول

إذا كنت تريد الاحتفاظ بــ System.out.println فقم بتشغيل ملف الجار من داخل Console Window باستخدام الامر java -jar jarfilename

الان بعد تشغيل الملف باستخدام ملف الجار وليس النت بينز ما هو الخطأ الذي يظهر لديك؟

لاحظ ان المجلد Current Directory الذي يعمل منه النت بينز ليس نفسه المجلد الذي يعمل منه ملف الجار الاصلي ، يعني حتى ولو اعطاك خطأ في النت بينز فسوف يعمل الملف الاصلي وهي الفكرة التي اريد ان اوصلها اليك من بداية الموضوع و هي ان المسار الذي ينفذ منه النت بينز البرنامج ليس نفس المسار الذي يعمل منه ملف الجار عند ضغطه مرتين بالماوس

تم تعديل هذه المشاركة بواسطة mental-driller في 26 أكتوبر 2012 في 02:18

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#18

حسنا فقط للتأكد انت تقوم بتشغيل الملف بالضغط على ملف الجار مرتين بالماوس وليس عن طريق النت بينز؟

حاول ازالة الــ root قبل اسم الملف "/ " اي قم بكتابة اسم ملف الصوت فقط. كما اني لا ادري لماذا يظهر File:/ قبل اسم الملف قم بإزالة toString() في الاستدعاء

Class.class.getClass().getResource("/sound1.wav").toString();

تأكد من اسم الرابط صحيح ولا يسبقه File:/ اي قم بطباعة اسم الملف في JOptionPane بعد السطر قبل انشاء الــ Thread

Class.class.getClass().getResource("/sound1.wav").toString();

تأكد ايضا من مسألة الــ case sensitiveness لاسم الملف

تم تعديل هذه المشاركة بواسطة mental-driller في 26 أكتوبر 2012 في 03:53

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#19
اقتباس
انت تقوم بتشغيل الملف بالضغط على ملف الجار مرتين بالماوس وليس عن طريق النت بينز؟

نعم

اقتباس
لا ادري لماذا يظهر File:/ قبل اسم الملف

أظن أن File هو البروتوكول المُستعمل للوصول إلى الملفات المحلية لأنني عندما نسخت الرابط السابق (بما في ذلك File) ووضعتُه في متصفح الملفات بويندوز تم الذهاب إلى المجلد classes

اقتباس
قم بإزالة toString في الاستدعاء

لا يمكنني ذلك لأن دالة بناء فئة الصوت تستقبل كائنا من نوع String و ليس URL مع أنني حاولت تغيير دالة البناء لتصبح هكذا :

public AePlayWave(URL wavfile) {
        filename = wavfile.toString();
        curPosition = Position.NORMAL;
    }

إلا أن الآم لم ينجح معي !

ملاحظة : عندما أكتب:

Thread playWave = new AePlayWave("C:\\Users\khaled\\Documents\\NetBeansProjects\\newProject\\src\\sound1.wav");

ثم أقوم بتنفيذ ملف الجار يتم تشغيل الملف الصوتي بنجاح و لكن إذا قمتُ بتغيير مكان ملف الصوت, ثم شغلت الجار مرة أخرى, يتعطل تشغيل ملف الصوت.

تم تعديل هذه المشاركة بواسطة khaled_prg في 26 أكتوبر 2012 في 09:57

#20

ليس عليك ان تقوم بقراءة ملف الصوت على شكل File تذكر ان FactoryMethod الخاصه بالفئة AudioInputStream يمكنك بناءها باستخدام InputStream لذا يمكنك القول

InputStream url = Fenetre.class.getClass().getResourceAsStream("/sound1.mp3");

لقد قمت بتغيير الكلاسات الخاصه بك لكي تاخذ InputStream بدلا من String كما قمت بحذف السطر الذي يبني File وقمت بتمرير الــ InputStream بدلا من تمرير الـFile

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication5;

import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.*;

public class AePlayWave extends Thread {

    private InputStream filename;
    private Position curPosition;
    private final int EXTERNAL_BUFFER_SIZE = 524288; // 128Kb

    enum Position {

        LEFT, RIGHT, NORMAL
    };

    public AePlayWave(InputStream wavfile) {
        filename = wavfile;
        curPosition = Position.NORMAL;
    }

    public void run() {
       // File soundFile = new File(filename);

        //if (!soundFile.exists()) {
          //  System.err.println("Wave file not found: " + filename);
            //return;
        //}

        AudioInputStream audioInputStream = null;
        try {
            audioInputStream = AudioSystem.getAudioInputStream(filename);
        } catch (UnsupportedAudioFileException e1) {
            e1.printStackTrace();
            return;
        } catch (IOException e1) {
            e1.printStackTrace();
            return;
        }

        AudioFormat format = audioInputStream.getFormat();
        SourceDataLine auline = null;
        DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

        try {
            auline = (SourceDataLine) AudioSystem.getLine(info);
            auline.open(format);
        } catch (LineUnavailableException e) {
            e.printStackTrace();
            return;
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        if (auline.isControlSupported(FloatControl.Type.PAN)) {
            FloatControl pan = (FloatControl) auline.getControl(FloatControl.Type.PAN);
            if (curPosition == Position.RIGHT) {
                pan.setValue(1.0f);
            } else if (curPosition == Position.LEFT) {
                pan.setValue(-1.0f);
            }
        }

        auline.start();
        int nBytesRead = 0;
        byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];

        try {
            while (nBytesRead != -1) {
                nBytesRead = audioInputStream.read(abData, 0, abData.length);
                if (nBytesRead >= 0) {
                    auline.write(abData, 0, nBytesRead);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            return;
        } finally {
            auline.drain();
            auline.close();
        }
    }
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication5;

import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import javax.swing.*;

public class Fenetre extends JFrame {

    public Fenetre() {
        Icon img = new ImageIcon(Class.class.getClass().getResource("/mygif.gif"));
        JFrame frame = new JFrame();
        JLabel label = new JLabel(img);
        frame.add(label);
        frame.setTitle("Fenêtre java");
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(String agr[])throws URISyntaxException,IOException {
        Fenetre test = new Fenetre();
        InputStream url = Fenetre.class.getClass().getResourceAsStream("/sound1.mp3");

        JOptionPane.showMessageDialog(null, url);
        Thread playWave = new AePlayWave(url);
        playWave.start();

    }
}

ولكن سوف تحصل على استثناء من نوع IOException لإن عملية الــ Mark/Reset ليست مدعومه من هذا النوع من الملفات ، عليك البحث عن ملفات صوت تدعم العملية، كما انصحك باستخدام JMF لانها اقوى في التعامل مع ملفات الفيديو

1

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#21

قمت بتغيير فئة الصوت و النتائج أصبحت كالتالي :

1. عندما أقوم بتشغيل الملف من النت بينز, تظهر الرسالة التالية :

post-225348-087035200 1351250185_thumb.p

و عند الضغط على OK يتم تشغيل الملف الصوتي.

2. عندما أقوم بتشغيل ملف الجار مباشرة, تظهر الرسالة التالية :

post-225348-065624500 1351250198_thumb.p

و عند الضغط على OK لا يتم تشغيل ملف الصوت !

المرفقات
1.png2.png
#22

على ما يبدو ان الرسالة تطبع اسم Reference اي انك تقوم بطباعة اسم الاوبجكت ، كما قلت لك لازالت لديك مشكلة دعم عمليتي الــ Mark/Reset حاول تشغيل اكثر من نوع من الملفات الصوتيه ، لكي ترى رسالة الخطأ في الــ Thread قم تشغيل ملف الجار من سطر الاوامر Command line or Powershell باستخدام الامر java -jar filename حتى ترى الــ printStacktrace .

No intellectual battle was ever won through retreat
You do not watch Gintama? Dude, you are missing a lot!


صورةmsrgb1485.gif ocajavase7programmerclr.gif

#23
اقتباس
حاول تشغيل اكثر من نوع من الملفات الصوتيه

لا يُمكنني تشغيل ملفات صوتية غير wav !

عندما أحاول مع mp3 تظهر الرسالة التالية :

javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input stream
	at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1102)
	at AePlayWave.run(AePlayWave.java:31)

اقتباس
قم تشغيل ملف الجار من سطر الاوامر

عند تشغيل ملف الجار من cmd تظهر الرسالة التالية :

java.io.IOException: mark/reset not supported
        at java.io.InputStream.reset(Unknown Source)
        at java.io.FilterInputStream.reset(Unknown Source)
        at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)

        at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
        at AePlayWave.run(AePlayWave.java:31)

علما أنني وضعت ملف صوتي من نوع wav لكي أستطيع توليد الجار.

#24

عملت لك برنامج بسيط يتعامل مع ملف الـ Wav , au فقط

واتمنى انه يساعدك ان شاء الله

Test Sound Play.zip

معذره حجم الملف كبير لانى وضعت بداخله ملف الصوت

بالتوفيق

1

Software Developer
Mahmoudkelany.com


 

#25

قمت بتجربة البرنامج و عمل معي بشكل أكثر من ممتاز :happy:

أشكرك من أعماق قلبي, أستاذي محمود :wub:

بارك الله فيك :)

أشكر أيضا الأستاذ mental الذي ساعدني كثيراً في فهم كيفية عمل فئة الصوت ..

كل الشكر لكم أحبتي و كل عام و أنتم بألف خير ..

بقي لدي سؤال واحد, لو سمحتم :

ملفات الــ wav حجمها كبير جداً مقارنة مع بقية الصيغ (mp3 على سبيل المثال).

ملف الجار أصبح حجمه كبير جداً (قرابة 30 Mb) !!

هل بالإمكان تصغير حجم الملف الصوتي ؟

مع العلم أنني قمت بتحويل صيغة الملف إلى mp3 لكنه لم يعمل !

تم تعديل هذه المشاركة بواسطة khaled_prg في 26 أكتوبر 2012 في 18:57

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…