Προς το περιεχόμενο

Visual C++ - Aποθηκευση χαρακτηριστικων βιντεο σε XML


SweetChild

Προτεινόμενες αναρτήσεις

Μου 'λαχε μια εργασία με θέμα την Καταχώρηση των χαρακτηριστικών ενός βίντεο (Mpeg-7) και εξαγωγή τους σε αρχείο XML και τώρα που τα βρήκα σκούρα σε ένα σημείο, χρειάζομαι την βοήθειά σας, όσο αυτή είναι εφικτή..

 

Συγκεκριμένα, θέλω ο χρήστης να ανοίγει ένα βίντεο, να σταματάει το βίντεο σε όποια σημεία θέλει (χρονικές στιγμές) και σε κάθε μία να καταχωρεί αυτά που βλέπει/θέλει. Π.χ. Φιλί, Brad Pitt, γαλάζιος ουρανός, κόκκινο παγκάκι...). Έπειτα να έχει την δυνατότητα να δημιουργεί και καταχωρεί και δικά του πεδία. Τα ήδη καταχωρημένα να φαίνονται στην φόρμα εκείνη με ενα tool 'StringGrid' για να μην καταχωρήσει απο αμέλεια τα ίδια.

 

69778128dn6.jpg

Form2: Καταχώρηση πεδίων για χρονικές στιγμές βιντεο. (Πρόχειρη εικόνα)

 

66746825ro6.jpg

Form3: Καταχώρηση extra πεδίων και εμφάνισής τους στο Grid..

 

Δεν βρίσκω την εντολή για το Grid για να έχει, σε πρώτη φάση, τα καταχωρημένα πεδία του Form2. Δλδ στα γκρι κουτάκια να εμφανίζονται οι τίτλοι καταχωρήσεων και στα ασπρα της 1ης γραμμης, αυτά που έγραψε ο χρήστης. :fear:

 

Ευχαριστώ εκ των προτέρων...

:-)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καταρχήν, το περιβάλλον που προγραμματίζεις δεν είναι η MS-Visual C++ αλλά ο CodeGear/Borland C++ Builder (έκδοση 6).

 

Για να γράψεις ή να διαβάσεις γρήγορα το περιεχόμενο κάθε cell ενός TStringGrid μπορείς να χρησιμοποιήσεις την TStringGrid->Cells[X][Y] = “Κείμενο”.

 

Για παράδειγμα:

>
StringGrid1->Cells[0][0] = "*";
StringGrid1->Cells[0][1] = "C0,1";
StringGrid1->Cells[0][2] = "C0,2";
StringGrid1->Cells[1][0] = "C1,0";
StringGrid1->Cells[1][1] = "TEXT";

 

Καλή συνέχεια.

 

Υ.Γ.

Αν σου αρέσει αυτό το περιβάλλον εργασίας, μπορείς να κατεβάσεις την δωρεάν έκδοση 2006 (CodeGear Trubo C++ Explorer) απο εδώ:

http://www.turboexplorer.com/cpp

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αν το πρόγραμμα που χρησιμοποιείς είναι αυτό που βλέπω στις εικόνες που ανάρτησες, τότε δεν πρόκειται για Visual C++ αλλά για C/C++ Builder (trust me).

 

Καλή συνέχεια.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Οι διαφορές είναι τεράστιες καθώς ο C/C++ Builder και η Microsoft Visual-C++ χρησιμοποιούν δυο εντελώς διαφορετικές βιβλιοθήκες γρήγορου προγραμματισμού.

 

Ο πρώτος βασίζεται στην VCL (Visual Component Library), στην οποία βασίζεται και η αδελφή του η Delphi, ενώ ο δεύτερος στην MFC (Microsoft Foundation Classes).

 

Ο κώδικας που γράφεις σε C/C++ Builder δεν μπορεί να γίνει port σε Visual C++ αν χρησιμοποιείς την VCL (εντολές ή components) καθώς η Microsoft δεν υποστηρίζει την τεχνολογία VCL.

 

Αντίστροφα ο κώδικας MFC μπορεί να γίνει compile από τον C/C++ Builder (ειδικά options), αλλά αν αρχίσεις να προγραμματίζεις σε VCL δύσκολα γυρνάς σε MFC, Windows API ή ακόμα και .NET framework (πρωτόγονα πράγματα) ;)

 

...

 

Τώρα περί κώδικα.. ας δούμε για παράδειγμα το TStringGrid, είναι ένα πανίσχυρο Text-Grid component της VCL, πάνω του μπορείς να χτίσεις γρήγορα μια ισχυρή εφαρμογή. Όμως δεν υπάρχει κάτι ανάλογο στην Visual-C++ ούτε καν στην .NET C# ώστε να το αντικαταστήσεις εκτός και αν αρχίσεις να ψάχνεις components τρίτων κατασκευαστών ...

 

Γενικά όταν δουλέψεις με τον C/C++ Builder καταλαβαίνεις τι πάει να πει εργαλείο RAD, ειδικά όταν σου επιτρέπει να χρησιμοποιείς C++ STL, VCL αλλά ( γιατί όχι; ) ακόμα και καθαρή C ή Windows API οπότε δύσκολα γυρνάς σε κάτι άλλο.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Οκ. Ασχολούμαι με C++ Builder. Κι εγώ νόμιζα ότι δεν έχει διαφορά.. Σόρρυ για το μπέρδεμα..

 

TStringGrid->Cells[X][Y] = “Κείμενο” ----> Ποια εντολή θα χρησιμοποιήσω για να παίρνει τους τίτλους από κάποια Labels ή Edits?

 

Βασικά, έχω βρει στο ιντερνετ ενα προγραμματακι, ονομαζομενο Video Editing. Και ειναι πανω κατω αυτο που χρειαζομαι...

Πως γινεται να βρω τον κωδικά του?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Απλά θα αντιγράφεις το ->Caption του Label ή το ->Text του edit.

 

πχ.

 

>
TStringGrid->Cells[0][0] = Label1->Caption;
TStringGrid->Cells[0][0] = Edit1->Text;

 

Υ.Γ.

Αυτές τις μέρες γράφω μια εφαρμογή και δεν παρακολουθώ φανατικά το forum

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

thanks και πάλι DirectX.. Η βοήθεια σου ειναι πολύτιμη...:-)

Βασικά το είχα δοκιμασει αυτό.. αλλά δεν μου το δεχτηκε. (το caption ανηκε σε αλλη φορμα και το ειχα γραψει οπως εσενα αλλα με Form1->Label1->Caption; ). Παρολα αυτα θα ξαναδοκιμασω....

 

Μήπως μπορέις να βοηθήσεις στο πως να κάνουμε το trackbar να πηγαίνει με τον χρόνο του video? Να προχωράει δλδ η μπάρα μαζί με το Play του video.

 

Δυστυχως δεν εχω καλα βιβλια, και πρεπει να οργανωθω λιγο. Δεν εχει και μια αξιολογη βιβλιοθηκη εδω περα... :mad:

 

Επίσης ξέρει κανεις (εμπειρος από mpεg-7) ποια ειναι τα βασικα πεδία της? Υπάρχουν καποια στανταρ δεδομενα πεδια για την mpeg-7 και μου ειναι απαραιτητα...

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Για να μετακινείς το knob μιας TTrackBar σύμφωνα με τον χρόνο του βίντεο όπως αυτό αναπαράγεται από το TMediaPlayer θα πρέπει να εξισώσεις την τιμή του TTrackBar->Position με εκείνη του TMediaPlayer->Position μέσα σε ένα TTimer που θα ανανεώνεται σχετικά γρήγορα (πχ. 100ns).

 

Για παράδειγμα, έστω ότι έχουμε στην φόρμα μας ένα TTimer component με την ονομασία Timer1, ο κώδικας που θα πρέπει να τοποθετηθεί στο OnTimer event του Timer1 θα μπορούσε να είναι ο παρακάτω:

>
   TrackBar1->Position = MediaPlayer1->Position;
   Caption = MediaPlayer1->Position;

 

*To Caption το ορίζω για να βλέπω εύκολα το MediaPlayer->Position (για γρήγορο debugging αν θες), μπορεί φυσικά να αφαιρεθεί.

 

Όμως δεν φτάνει μόνο αυτό καθώς αφού ορίσουμε το βίντεο που θέλουμε να φορτώσουμε (TMediaPlayer->FileName και ύστερα TMediaPlayer->Open()) θα πρέπει να «εξηγήσουμε» στο TMediaPlayer σε τι μορφή χρόνου θέλουμε να μας επιστρέψει το MediaPlayer->Position, αυτό γίνεται από το property MediaPlayer->TimeFormat και η πιο εύκολα χρησιμοποιούμενη μορφή χρόνου (που δεν χρειάζεται περαιτέρω εντολές [MACRO] από το Windows API –MCI για να χρησιμοποιηθεί) είναι η tfMilliseconds.

 

Για να ορίσουμε την μορφή χρόνου (αν δεν είναι ήδη σε tfMilliseconds) μπορούμε κατά την εμφάνιση της φόρμας μας (OnShow event) ή κατά το φόρτωμα του βίντεο (σε κάποιο άλλο Event..) να ορίσουμε το tfMilliseconds έτσι:

 

>
   MediaPlayer1->Open();
   MediaPlayer1->TimeFormat = tfMilliseconds;
   TrackBar1->Max = MediaPlayer1->Length; 

 

* Με την εντολή ->Open() ζητάμε από τον TMediaPlayer να δοκιμάσει να ανοίξει το αρχείο που επιθυμούμε και έχουμε νωρίτερα ορίσει στην ιδιότητα TMediaPlayer->FileName (μπορούμε να αφαιρέσουμε το ->Open() αν ορίσουμε το TMediaPlayer->AutoEnable σε true από τον Object Inspector). Ύστερα ορίζουμε το ->TimeFormat του MediaPlayer μας και τέλος ορίζουμε την μάξιμουμ τιμή που δέχεται το TTrackBar μας ώστε να ισούται με την συνολική διάρκεια του αρχείου που σκοπεύουμε να αναπαράγουμε από το MediaPlayer (->Length).

 

Τέλος, αν θέλουμε όταν πατάμε ξανά το Play του MediaPlayer, αυτός να ξεκινά την αναπαραγωγή του βίντεο πάντα από την αρχή, θα πρέπει θέσουμε το TMediaPlayer->Position = TMediaPlayer->Start πράγμα που γίνεται στο OnClick event του TMediaPlayer ως εξής:

 

>
   if(Button==btPlay)
       MediaPlayer1->Position = MediaPlayer1->Start;

 

* Αν το Button που κάναμε κλικ είναι το Play (btPlay) τότε θέτουμε το TMediaPlayer Position = Start.

 

Καλή συνέχεια.

 

Υ.Γ.

To Sample (δοκιμαστικό) AVI (mediaexample.avi) που χρησιμοποίησα προέρχεται από εδώ: http:// http://support.microsoft.com/kb/316992.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

:-D;) Όντως δουλευει ετσι...

 

Το μόνο που δεν μπορώ να κάνω είναι να αλλάζει το χρονόμετρο όταν θα σέρνω την μπάρα του trackbar..

 

Πως να κάνω να αλλάζει το μέγεθος του Animate ανάλογα με το μέγεθος του Video που βάζω να προβάλει?..

 

Και μια ερώτηση διφορετικού περιεχομένου κάπως... Η C# είναι διαφορετική από την C++?? Και ποια είναι πιο ευχρηστη (να εχει και περισσότερα components)?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Για να επιτύχεις την μετακίνηση του βίντεο στο σημείο που υποδεικνύει το TTrackBar knob θα πρέπει να προσθέσεις τον παρακάτω κώδικα στο OnChange event του TrackBar σου, επίσης για οπτική πληρότητα καλό είναι να θέσεις το AutoEnabled του TMediaPlayer σε false ώστε να διαχειρίζεσαι εσύ την κατάσταση των πλήκτρων του TMediaPlayer σου.

 

>
   if(HIBYTE(GetKeyState(VK_LBUTTON)) && MediaPlayer1->Mode!=mpNotReady)
    {
       if(FindVCLWindow(Mouse->CursorPos)==TrackBar1)
        {
           MediaPlayer1->PauseOnly();
           MediaPlayer1->EnabledButtons = MediaPlayer1->EnabledButtons >> btPlay >> btPause; 
           MediaPlayer1->Position = TrackBar1->Position;
           MediaPlayer1->Tag = 5;
        }
    }
   else
       if(MediaPlayer1->Tag==5)
        {
           MediaPlayer1->Tag = 0;
           MediaPlayer1->Resume();
           MediaPlayer1->EnabledButtons = MediaPlayer1->EnabledButtons << btPlay << btPause;            
        } 

 

* Η παραπάνω μέθοδος ελέγχει εάν η αλλαγή θέσης του knob γίνεται από το mouse του χρήστη και αν συμβεί αυτό, διακόπτει προσωρινά την αναπαραγωγή του βίντεο (pause) και επανακαθορίζει την μετέπειτα θέση αναπαραγωγής θέτοντας το TMediaPlayer->Position ως ίσον του TTrackBar1->Position, μόλις τελειώσουμε με την διαχείριση του knob κάνει Resume.

Ο έλεγχος που κάνω ώστε να διακρίνω εάν το OnChange event προέρχεται από το event του TTimer ή από το χρήστη, γίνεται με την βοήθεια της Windows API ρουτίνας GetKeyState η οποία επιστρέφει στο HIBYTE της 1 όταν ένα πλήκτρο είναι πατημένο και 0 όταν απελευθερωθεί. Επίσης ελέγχω αν ο TMediaPlayer είναι έτοιμος για αναπαραγωγή (ediaPlayer1->Mode!=mpNotReady).

Ευτυχώς τα Windows επιτρέπουν στην GetKeyState να αναγνώσει την κατάσταση και των πλήκτρων του Mouse –στην περίπτωση μας, του Αριστερού (VK_LBUTTON).

 

Δεν φτάνει όμως μόνο αυτό, καθώς πρέπει να εξασφαλίσουμε πως η διακοπή του βίντεο με αριστερό κλικ γίνεται μόνο όταν το ποντίκι είναι πάνω στο TTrackBar component.

Σε φυσιολογικές συνθήκες αυτό είναι αυτόματο, καθώς το OnChange event ενεργοποιείται μόνο όταν ο χρήστης αλλάξει το control, στην περίπτωση μας όμως το OnChange event ενεργοποιείται αυτόματα και από τον κώδικα του TTimer οπότε για να διακρίνουμε τις περιπτώσεις θα χρησιμοποιήσουμε την θέση του Mouse στην φόρμα ώστε να εκτελείται ο κώδικας μας μόνο όταν το Click του mouse γίνεται πάνω στο TTrackBar component.

 

Αυτός ο έλεγχος γίνεται με την συνθήκη:

>
if(FindVCLWindow(Mouse->CursorPos)==TrackBar1)
        { }

 

*Η FindVCLWindow επιστρέφει το TWinControl που βρίσκεται στις συντεταγμένες TPoint (δηλαδή x,y) του Mouse (Mouse->CursorPos) οπότε αν το TWinControl==TrackBar1, τότε πια κάνουμε την αλλαγή της θέσης αναπαραγωγής του βίντεο και ορίζουμε το Tag του TMediaPlayer σε 5 (θα δούμε γιατί παρακάτω), ύστερα απενεργοποιούμε τα πλήκτρα btPlay Και btPause του TMediaPlayer και συνεχίζουμε ακάθεκτοι..

 

Εδώ υπάρχει ένα πρόβλημα, θα πρέπει να εξασφαλίσουμε πως όταν το OnChange event εκτελείται δίχως ο χρήστης να έχει μετακινήσει το Knob του TTrackBar δεν θα κάνει αδιάκοπο Resume. Σε μια τέτοια περίπτωση το Resume και Stop απλά θα παύανε να δουλεύουν, οπότε .. για να διακρίνουμε πότε θα πρέπει να εκτελέσουμε το Resume κάνουμε τα εξής:

>
   else
       if(MediaPlayer1->Tag==5)
        {
           MediaPlayer1->Tag = 0;
           MediaPlayer1->Resume();
           MediaPlayer1->EnabledButtons = MediaPlayer1->EnabledButtons << btPlay << btPause;
        }

 

Αν το Pause προέρχεται από εμάς τότε το Tag του TMediaPlayer θα πρέπει να ισούται με 5 οπότε σε αυτή την περίπτωση κάνουμε ->Resume και επαναφέρουμε τα πλήκτρα btPlay και btPause του MediaPlayer μας διαφορετικά δεν κάνουμε τίποτε.

 

Υ.Γ.

1. Η χρήση του ->EnabledButtons TSet είναι απαραίτητη καθώς στην δικιά μου έκδοση του C/C++ Builder (6.0) μετά το ->Resume τα πλήκτρα Play & Pause παραμένουν ανενεργά.

2. Μπορεί να υπάρχουν πολύ πιο αποδοτικές λύσεις στο ερώτημα σου, εγώ αυτή έφτιαξα και δημοσίευσα ;)

3. Η σωστή ερώτηση είναι, C# ή C/C++ Builder και VCL; :D

 

Καλή συνέχεια.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...