Je sais utiliser Je demande car, à l'aide de la méthode de style de tirage - AvasSetreader CODE> et
AvaisetWriter CODE>, et les avez utilisé avec succès pour saisir une piste vidéo d'un film et transcodez-la dans une autre. Cependant, j'aimerais faire cela avec l'audio aussi. Dois-je créer et
AvasseTExportsession CODE> après que j'ai terminé avec le transcode initial, ou existe-t-il un moyen de basculer entre les pistes au milieu d'une séance d'écriture? Je détesterais devoir faire face aux frais généraux d'un
avaissetexportsession code>. P>
tandis que ([ASTRETWRITRINPUT ISREADYFORMEDIADATA]) {...} code> - suppose une piste seulement. Comment pourrait-il être utilisé pour plus d'une piste, c'est-à-dire à la fois un audio et une piste vidéo? P>
3 Réponses :
Avez-vous essayé d'utiliser deux avaisetwriterinput et poussant les échantillons à travers une file d'attente de travailleur? Voici un croquis approximatif.
processing_queue = dispatch_queue_create("com.mydomain.gcdqueue.mediaprocessor", NULL); [videoAVAssetWriterInput requestMediaDataWhenReadyOnQueue:myInputSerialQueue usingBlock:^{ dispatch_asyc(processing_queue, ^{process video}); }]; [audioAVAssetWriterInput requestMediaDataWhenReadyOnQueue:myInputSerialQueue usingBlock:^{ dispatch_asyc(processing_queue, ^{process audio}); }];
Merci pour la suggestion. Je l'ai essayé, mais je n'ai pas pu comprendre comment terminer correctement la session d'écriture. Avec une piste, je viens de voir si la copie -extsampluffer retourne vide, puis terminez la session. Avec plusieurs pistes, j'ai essayé de créer un drapeau lorsque l'audio ou la vidéo a été effectuée et si les deux étaient complètes, je terminerais la session. Cependant, même si j'ai fait une vérification du statut de lecteur d'actif étant avastsereaderstatusreading, j'ai continué à obtenir l'erreur: [AvastreeaderAkTrackutput CopyNextsampluffer] ne peut pas copier le tampon d'échantillon suivant, à moins que le lecteur d'actif ne soit dans l'état "Lecture"
Je parierai à tester une stratégie comme celle-ci dans un proche avenir. Si je trouve une solution, je posterai.
Appelez-vous [avastetwriterinput markasfini]; Dans votre méthode de demandeMediawawhenReadyOnqueur? Je n'appellerais pas de cette méthode du tout, mais plutôt d'appeler la fin de course sur l'avaisetwriter lorsque tout est complet.
Désolé pour la réponse tardive, je n'ai pas été informé du commentaire. Je n'appelle que le finisseur d'arrivée, tout comme vous faites.
À propos, votre erreur "Lecture" State "peut en réalité être un problème de codec. Si les entrées et les sorties ne sont pas des formats compatibles qui sont la façon dont il va parfois surface.
Vous n'avez besoin que d'un Avaisetwriter CODE> interstilisera automatiquement les demandes sur son
avastetwriterinput code> S afin d'intégrer différentes pistes dans le fichier de sortie. Il suffit d'ajouter un
avaissetwriterinput code> pour chacune des pistes que vous avez, puis appelle
DemandeMediatawhenreadyonQueue: UtilisationBLOCK: Code> sur chacun de vos
Avaisetwriterinput code> s. > Voici une méthode que j'ai cet appels
DemandeMediatawhenreadyONOnQueue: UtilisationBlock: code>. J'appelle cette méthode à partir d'une boucle sur le nombre de paires de sortie / d'entrée que j'ai. (Une méthode distincte est bonne à la fois pour la lisibilité du code et également parce que, contrairement à une boucle, chaque appel définit un cadre de pile séparé pour le bloc.) P>
DisPatch_Queue_t code> et peut le réutiliser pour toutes les pistes. Notez que vous devriez définitivement pas em> appel
DISTATCH_ASYNC code> à partir de votre bloc, car
DemandeMediatawhenreadyonQueue: UtilisationBLOCK: CODE> attend le blocage, eh bien, bloquer jusqu'à ce qu'il soit rempli Dans autant de données que le
avastetwriterinput code> prendra. Vous ne voulez pas revenir avant alors. P>
- (void)requestMediaDataForTrack:(int)i {
AVAssetReaderOutput *output = [[_reader outputs] objectAtIndex:i];
AVAssetWriterInput *input = [[_writer inputs] objectAtIndex:i];
[input requestMediaDataWhenReadyOnQueue:_processingQueue usingBlock:
^{
[self retain];
while ([input isReadyForMoreMediaData]) {
CMSampleBufferRef sampleBuffer;
if ([_reader status] == AVAssetReaderStatusReading &&
(sampleBuffer = [output copyNextSampleBuffer])) {
BOOL result = [input appendSampleBuffer:sampleBuffer];
CFRelease(sampleBuffer);
if (!result) {
[_reader cancelReading];
break;
}
} else {
[input markAsFinished];
switch ([_reader status]) {
case AVAssetReaderStatusReading:
// the reader has more for other tracks, even if this one is done
break;
case AVAssetReaderStatusCompleted:
// your method for when the conversion is done
// should call finishWriting on the writer
[self readingCompleted];
break;
case AVAssetReaderStatusCancelled:
[_writer cancelWriting];
[_delegate converterDidCancel:self];
break;
case AVAssetReaderStatusFailed:
[_writer cancelWriting];
break;
}
break;
}
}
}
];
}
Qu'est-ce qui est avec le [auto retenue] code>? Est-ce que cela ne veut que continuer à incrémenter le nombre de retenons sur l'objet un montant arbitraire? Qui relâche cet objet?
L'intention a peut-être pu être pour LectureCompleted code> pour libérer l'objet. Cela étant dit, il peut être inutile que la présence de la
[auto lecturecommée] appelle code> doit faire conserver le temps d'exécution
auto / code> automatiquement.
Vous pouvez utiliser des groupes d'expédition!
Consultez l'exemple AvreaderWriter pour macosx ... p>
Je cite directement à partir de l'échantillon rwdocument.m: p>
Remarquez la commande de premier groupe Notify à la fin de savoir quand tout audio / vidéo est terminé ... C'est un rendu hors écran ... pas un temps réel
"Offscreen" et "temps réel" ne sont pas des contraires; "Rendu" et "Off-Screen" sont (et font). "Real-Time" est subjectif à un observateur et décrit le taux d'affichage des cadres vidéo comme ils sont acquis à partir de leur source. Il n'a pas d'opposition, pas même "non réel". Vous ne voudriez pas qu'un transcodeur fonctionne à un rythme en temps réel. Le transcodage devrait arriver le plus rapidement possible; Il existe des dispositifs dédiés à cela dans l'industrie de la radiodiffusion. Rien ne va plus lentement que la normale en temps réel, de toute façon. Même le logiciel de lecture doit peser une vidéo pour le garder d'affichage plus rapide qu'il ne peut être perçu.
Seriez-vous capable de me diriger dans la bonne direction pour apprendre à transcoder à l'aide d'Avaisetwriter? Je cherche juste à transcoder un bittrate et une résolution plus bas?