[C#]MPEG niet te verwijderen na omzetten naar WMV

Pagina: 1
Acties:

  • Arie-Kanarie
  • Registratie: Juli 2004
  • Laatst online: 21-06-2025

Arie-Kanarie

Een keer wat anders

Topicstarter
Hallo,

Ik heb een windows service geschreven in C# (.NET1.1).
Deze service download .MPG bestanden van een ftpserver om er volgens een .WMV van te maken, welke daarna weer geupload wordt. Als dit gedaan is moeten beide bestanden weer van de pc verwijderd worden.
Dit werkt allemaal goed tot het verwijderen.
De .wmv die gegeneerd is met Windows Media Encoder wordt netjes verwijderd. De .mpg file alleen als deze geen geluid bevat. Dit zijn bijvoorbeeld filmpjes die gemaakt zijn door een aantal plaatjes achter elkaar te zetten met diverse overgangen en daar dan een filmpje van te genereren.

Als ik de mpg in explorer probeer te verwijderen krijg ik de melding dat deze nog in gebruik is door een ander programma. Als ik in code de file exclusief probeer te openen krijg ik dezelfde exception.
Om de bestanden te verwijderen gebruik ik de volgende code:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
foreach (string bestandsnaam in bestanden)
{
    //FileStream tmpStream;
    //try
    //{
        //  tmpStream = File.Open(TEMPDIR + bestandsnaam, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
        //  tmpStream.Close();
                
        System.IO.FileInfo tmp = new System.IO.FileInfo(TEMPDIR + bestandsnaam);
        if (tmp.Exists)
        {
            tmp.Delete();
        }
        else
        {
            Logger.Write("File: " + tmp.FullName + " doesnt exist");
        }

        if (System.IO.File.Exists(TEMPDIR + bestandsnaam))
        {
            deletedFiles += "- File: " + TEMPDIR + bestandsnaam + " not deleted \n";
        }
        else
        {
            deletedFiles += "- Deleted file: " + TEMPDIR + bestandsnaam + "\n";
        }
    //}
    //catch (Exception err)
    //{
    //  SchrijfError("Bestand kon niet geopend of verwijderd worden", err);
    //}
}

(excl. openen staat nog als commentaar, was alleen om ff te testen)
Deze code gooit geen exceptions (staat nog try catch om de for loop om dit af te vangen), maar de mpg bestanden worden ook niet verwijderd, totdat ik de service stop. Dan verdwijnen plotseling alle bestanden en is de directory weer leeg.

Waar in vredesnaam kan die aanliggen? Ik heb al geprobeerd standaard te encoden zonder geluid, maar ook dit mocht niet baten.
Om te encoden heb ik gewoon het voorbeeld dat bij de media encoder sdk zat gebruikt, alleen gebruik ik geen bestand als profiel, maar maak ik in code een profiel met de gewenste instellingen aan.

Tis gemaakt in VS.NET 2003 en de service gedraagt zich op Win XP en Win 2003 hetzelfde. Als refrence heb ik Interop.WMEncoderLib om te encoden, verder nog een refrence naar een dll voor FTP en nog wat linkjes naar dll'tjes uit de EnterpriseLibrary van windows (voor db communicatie en logging) bij alle refrences staat Copy Local op true.

Ik hoop dat iemand iets van een tip of oplossing heeft. Anders zit er niet veel anders op dan om de zoveel tijd een keer de service opnieuw te starten. Maar dit heb ik liever niet natuurlijk.

Software ontwikkelen in de Achterhoek voor leuke klanten door heel Nederland? Klik hier


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:29
Je service zal die files nog locken.
Ergens een close vergeten...

[ Voor 29% gewijzigd door whoami op 04-10-2006 14:46 ]

https://fgheysels.github.io/


  • Arie-Kanarie
  • Registratie: Juli 2004
  • Laatst online: 21-06-2025

Arie-Kanarie

Een keer wat anders

Topicstarter
whoami schreef op woensdag 04 oktober 2006 @ 14:46:
Je service zal die files nog locken.
Ergens een close vergeten...
hmm, het gekke is ik open nergens een file.. tenminste niet expliciet dmv. een filestream oid.
het zijn eigenlijk maar een paar functies, die na elkaar worden uitgevoerd (als de vorige is gelukt)
DownloadClip() //download mpg van server
SetClipframes() //vult het aantal frames van de clip in in de database
GeneratePreview() //genereert een wmv van de mpg dmv de windows media encoder
UploadPreview() //uploadt de wmv naar de server
CleanUpTemp() //verwijderd de bestanden (zie startpost)

Heb al geprobeerd de SetClipFrames functie te skippen, maar dan lukt het verwijderen van de mpg bestanden dus nog steeds niet (alleen als deze bestanden geluid hebben)

Volgens mij zit het dus in de GeneratePreview(), code hiervan is als volgt:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
try 
{
    // Create a WMEncoder object.
    WMEncoder Encoder = new WMEncoder();
    Encoder.OnStateChange += new _IWMEncoderEvents_OnStateChangeEventHandler(OnStateChange);            

    // Retrieve the source group collection.
    IWMEncSourceGroupCollection SrcGrpColl = Encoder.SourceGroupCollection;

    // Add a source group to the collection.
    IWMEncSourceGroup SrcGrp = SrcGrpColl.Add("SG_1");

    MPEGHeaderReader.MpegInfo clipInfo = new MPEGHeaderReader.MpegInfo(inputFile);
    clipInfo.Parse();
                
    if(clipInfo.AudioInfo.Duration > 0)
    {
        // Add a video and audio source to the source group.
        IWMEncAudioSource SrcAud = (IWMEncAudioSource)SrcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_AUDIO);
        SrcAud.SetInput(inputFile, "", "");
        hasAudio = true;
    }               

    IWMEncVideoSource2 SrcVid = (IWMEncVideoSource2)SrcGrp.AddSource(WMENC_SOURCE_TYPE.WMENC_VIDEO);
    SrcVid.SetInput(inputFile, "", "");             

    // Crop 2 pixels from each edge of the video image.
    SrcVid.CroppingBottomMargin = 2;
    SrcVid.CroppingTopMargin = 2;
    SrcVid.CroppingLeftMargin = 2;
    SrcVid.CroppingRightMargin = 2;

    // Specify a file object in which to save encoded content.
    IWMEncFile File = Encoder.File;
    File.LocalFileName = TEMPDIR + outputFile + ".wmv";
                
    // Gebruik ons eigen profiel
    IWMEncProfile Pro = ibPreviewProfile(hasAudio);
    SrcGrp.set_Profile(Pro);
            
    // Fill in the description object members.
    IWMEncDisplayInfo Descr = Encoder.DisplayInfo;
    Descr.Author = "bedrijfsnaam";
    Descr.Copyright = "Copyright by My";
    Descr.Description = "Preview generated for " + inputFile.Substring(pos+1); //alleen filename+extensie
    Descr.Title = clipNaam + " (preview)";

    // Start the encoding process.
    // Wait until the encoding process stops before exiting the application.
    Logger.Write("Start of encoding: " + inputFile);
    Encoder.PrepareToEncode(true);
    Encoder.Start();
    while (_bDone == false)
    {
        //just wait
    }               
    //De source weer verwijderen uit de collectie zodat de encoder de source niet meer in gebruik heeft
    //Anders kan de source niet uit de temp directory verwijderd worden
    for (int i=0; i < Encoder.SourceGroupCollection.Count; i++)
    {
        Encoder.SourceGroupCollection.Remove(i);
    }

    Logger.Write("End of encoding: " + inputFile);
}

Maar waar kan het inzitten? Het is gewoon het voorbeeld uit de handleiding van de SDK, zelfs het commentaar is mee gekopieerd ;)
Wat ik toegevoegd heb is de laatste for loop, maar volgens mij doet dat ook niet helemaal wat ik wil dat het doet.
Zou het de eventhandler kunnen zijn?
Dit bedenk ik me tijdens het tikken van deze post. Maar als ik die verwijderd kan ik volgens mij niet echt controleren of de encoder al klaar is...

Software ontwikkelen in de Achterhoek voor leuke klanten door heel Nederland? Klik hier


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:29
Moet die 'Encoder' niet gedisposed worden oid als je 'm niet meer gebruikt ?

https://fgheysels.github.io/


  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 12-02 21:39

TeeDee

CQB 241

.Close() en/of een .Dispose() ergens vergeten lijkt mij het meest waarschijnlijkste.

Heart..pumps blood.Has nothing to do with emotion! Bored


  • Arie-Kanarie
  • Registratie: Juli 2004
  • Laatst online: 21-06-2025

Arie-Kanarie

Een keer wat anders

Topicstarter
whoami schreef op woensdag 04 oktober 2006 @ 15:12:
Moet die 'Encoder' niet gedisposed worden oid als je 'm niet meer gebruikt ?
Volgens het voorbeeld niet... maar dat zegt natuurlijk niet alles ;)
Encoder object bevat geen dispose. Heb nu het volgende toegevoegd:
File = null;
Encoder.Stop();
Encoder = null;

Maar ook dat helpt niet echt. Als ik met het programma unlocker kijk maakt er tijdens het downloaden 1 proces gebruik van de MPG, als het encoden start komt er een 2e proces bij. Als het encoden klaar is blijft dit proces gebruik maken van het bestand :(
Ook maak nu geen gebruik meer van ons eigen profiel, maar van 1 van de standaard profielen. Maar dat helpt ook niet.
Verder kan ik geen .Close() of .Dispose() op 1 van de objecten die ik gebruik bij het encoden aanroepen.

Ik zal het ook nog eens proberen met een gewone applicatie.

[ Voor 6% gewijzigd door Arie-Kanarie op 04-10-2006 17:06 ]

Software ontwikkelen in de Achterhoek voor leuke klanten door heel Nederland? Klik hier


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:29
Die encoder, is dat een COM object ?
Indien ja: probeer het dan eens zo:
code:
1
Marshal.ReleaseComObject (encoder);

https://fgheysels.github.io/


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

http://www.sysinternals.com/Utilities/Filemon.html

probeer dit maar eens uit om exact te weten welk proces jouw file nog heeft openstaan.

ASSUME makes an ASS out of U and ME


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Ahem.

C#:
1
2
3
4
    for (int i=0; i < Encoder.SourceGroupCollection.Count; i++)
    {
        Encoder.SourceGroupCollection.Remove(i);
    } 

Als je dingen uit een lijst gaat verwijderen en je gebruikt de Count of Length van die lijst in je for-loop, dan moet je nooit je teller verhogen aan het einde van de loop. Dat verklaart ook waarom het alleen gebeurt bij clips die geluid hebben. Die hebben namelijk 2 'source groups'. Jouw loopje verwijdert item 0 (video). Op dat moment wordt wat item 1 (geluid) was item 0, en de Count wordt 1 in plaats van 2. Daarna wordt i verhoogt naar 1, waardoor i < Count onwaar wordt, dus wordt het tweede item nooit verwijderd. Je loopje moet als volgt worden:
C#:
1
2
3
4
    for (int i=0; i < Encoder.SourceGroupCollection.Count;)
    {
        Encoder.SourceGroupCollection.Remove(i);
    } 

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:29
Of gewoon van achter naar voor lopen:
code:
1
2
3
4
for( int i = Encoder.SourceGroupCollection.Count - 1; i >= 0; i-- )
{
   Encoder.Remove(i);
}

Dat vind ik persoonlijk duidelijker en netter dan het weglaten van de increment of decrement

[ Voor 24% gewijzigd door whoami op 05-10-2006 09:10 ]

https://fgheysels.github.io/


  • Arie-Kanarie
  • Registratie: Juli 2004
  • Laatst online: 21-06-2025

Arie-Kanarie

Een keer wat anders

Topicstarter
@whoami:
1. Ja het is volgens mij een com object, dwz. als ik in vs.net 2003 bij add refrence kijk, vind ik um onder het tabblad COM.
2. Die for loop van jou kan ik me inderdaad wel in vinden (wat betreft netter etc.), maar heb toch die van Korben gebruikt :p .

@Korben:
doh... dat ik daar niet op ben gekomen. Had me heel wat uren gescheelt. Toen ik je uitleg las dacht ik: och jah dom dom, logisch.
Dus meteen geprobeerd en wat bleek: dat was het. (dwz. heb nu voor 1 clip getest en daar deed ie nu wel wat ie moest doen, dus gok dat het met de rest ook goed gaat)
Dat je om 2 uur snachts op zon idee moet komen ;)

in ieder geval hartelijk dank u allen

Software ontwikkelen in de Achterhoek voor leuke klanten door heel Nederland? Klik hier


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

whoami schreef op donderdag 05 oktober 2006 @ 08:53:
Of gewoon van achter naar voor lopen:
code:
1
2
3
4
for( int i = Encoder.SourceGroupCollection.Count - 1; i >= 0; i-- )
{
   Encoder.Remove(i);
}

Dat vind ik persoonlijk duidelijker en netter dan het weglaten van de increment of decrement
Of gewoon:
C#:
1
2
3
4
5
int length = Encoder.SourceGroupCollection.Count;
for (int i = 0; i < length; i++)
{
   Encoder.Remove(i);
}

Dat is nog netter, imo. En sneller.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • mulder
  • Registratie: Augustus 2001
  • Nu online

mulder

ik spuug op het trottoir

Korben schreef op donderdag 05 oktober 2006 @ 14:36:
[...]

Of gewoon:
C#:
1
2
3
4
5
int length = Encoder.SourceGroupCollection.Count;
for (int i = 0; i < length; i++)
{
   Encoder.Remove(i);
}

Dat is nog netter, imo. En sneller.
Dat gaat fout. Count is 10, na 1 verwijderen is de Count 9. Index blijft oplopen tot 10.

oogjes open, snaveltjes dicht


  • whoami
  • Registratie: December 2000
  • Laatst online: 11:29
Wat Don Facundo zegt; je length blijft steeds op 10.

Trouwens, dat is 'micro-optimizen', en is niet sneller. Als je die Length in je for conditie laat staan, dan zal de CLR zelf wel bepalen of hij het moet optimizen of niet, en dat zal nog altijd sneller zijn....
Ff zien of ik nog dat artikel kan terugvinden...

Don't try to out think the compiler
klik

[ Voor 26% gewijzigd door whoami op 05-10-2006 14:52 ]

https://fgheysels.github.io/


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

whoami schreef op donderdag 05 oktober 2006 @ 14:48:
Wat Don Facundo zegt; je length blijft steeds op 10.

Trouwens, dat is 'micro-optimizen', en is niet sneller. Als je die Length in je for conditie laat staan, dan zal de CLR zelf wel bepalen of hij het moet optimizen of niet, en dat zal nog altijd sneller zijn....
Ff zien of ik nog dat artikel kan terugvinden...
True, mijn methode gaat inderdaad fout, maar niet als je 0 gebruikt in die aanroep naar Remove(). Was ook maar net wakker. :P

Bovendien, dit is een aanroep naar een COM-functie. Lijkt me niet dat de compiler/CLR dat kán optimizen. Een array.Length kan ik me inderdaad voorstellen.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
C#:
1
2
3
while (Encoder.SourceGroupCollection.Count > 0) {
  Encoder.Remove(0); 
}

:? Of denk ik nou zo raar?

[ Voor 13% gewijzigd door RobIII op 05-10-2006 15:13 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • mulder
  • Registratie: Augustus 2001
  • Nu online

mulder

ik spuug op het trottoir

RobIII schreef op donderdag 05 oktober 2006 @ 15:09:
C#:
1
2
3
while (Encoder.SourceGroupCollection.Count > 0) {
  Encoder.Remove(0); 
}

:? Of denk ik nou zo raar?
Ondanks dat dat er wel cool uitziet, is het wel efficienter? Ik heb nu het idee dat je nu alle elementen steeds 1 naar voren moet halen, maar dat ligt ook weer aan het Type natuurlijk?

oogjes open, snaveltjes dicht


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Don Facundo schreef op donderdag 05 oktober 2006 @ 15:20:
[...]
Ondanks dat dat er wel cool uitziet, is het wel efficienter? Ik heb nu het idee dat je nu alle elementen steeds 1 naar voren moet halen, maar dat ligt ook weer aan het Type natuurlijk?
Zoals gezegd zijn dit micro-optimizations en bereik je in het overgrote deel dat je ze gebruikt zowieso geen (echte) snelheidswinst. Het is enkel een manier van "notatie" om je collection leeg te gooien. Hoe je dat doet wordt hier op meerdere manieren getoond en ik postte gewoon mijn manier ;)

Om toch even op je vraag in te gaan; ik verwacht niet dat objecten "naar voren" worden gehaald, geheugen wordt nu gewoon aan het begin van de collection vrijgegeven in plaats van aan het eind en verder is het gewoon wat schuiven met pointers waarschijnlijk. Ik vermoed niet dat 't "meer" kost dan andere methodes (maar om dat zeker te weten zou ik het even moeten onderzoeken, en daar heb ik helaas nu geen tijd voor ;) )

[ Voor 25% gewijzigd door RobIII op 05-10-2006 15:40 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • mulder
  • Registratie: Augustus 2001
  • Nu online

mulder

ik spuug op het trottoir

Agreed, ik dacht mocht het geheugen 'naar voren' gehaald worden dan zal het zeker toch wel minder efficient worden bij een grote collectie, maar ik denk idd dat er geen reden is om geheugen te gaan verplaatsten.

oogjes open, snaveltjes dicht

Pagina: 1