2012-05-03 17 views
16

To dość frustrujące. Próbuję uzyskać rozmiar zestawu AVURLasset, ale staram się unikać naturalSize, ponieważ Xcode mówi mi, że jest przestarzałe w iOS5.AVURLAsset pobiera rozmiar wideo

Ale: Jaka jest wymiana?

nie mogę znaleźć żadnego pojęcia o tym, jak uzyskać wideo-wymiary bez użycia «naturalsize» ...

Odpowiedz

20

Właśnie sprawdziłem dokumentację online, a metoda naturalSize jest przestarzała dla obiektu AVAsset. Jednak zawsze powinien istnieć AVAssetTrack, który odnosi się do zestawu AVA, a AVAssetTrack ma metodę naturalSize, którą możesz wywołać.

naturalSize

naturalne wymiary nośników danych przywoływanych przez tory. (Tylko do odczytu)

@property (nonatomic, tylko do odczytu) CGSize naturalSize

Dostępność

Dostępne w iOS 4.0 i nowszych. Zadeklarowane w AVAssetTrack.h

Via "Użyj naturalSize i preferredTransform, w stosownych przypadkach, wideo składnika aktywów tory zamiast (patrz również tracksWithMediaType:)" AVAssetTrack Reference for iOS

+0

'nautralSize' jest przestarzałe w iOS 5 – Raptor

+0

właśnie sprawdził dokumenty w odnośniku w odpowiedzi i nie jest przestarzały, jest dostępny zarówno w ObjC, jak iw Swift –

+14

w dokumentacji są 2 'naturalSize'. "AVURLAsset.naturalSize" jest przestarzałe, ale '[[[videoAsset tracksWithMediaType: AVMediaTypeVideo] objectAtIndex: 0] naturalSize]' nie jest – Raptor

24

deprecation warning on the official documentation sugeruje,

zmieniłem kod:

CGSize size = [movieAsset naturalSize]; 

do

CGSize size = [[[movieAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize]; 

To mniej ładna i mniej bezpieczne, ale teraz nie złamie, kiedy spadnie tę metodę.

13

Ostrzeżenie deprecation mówi:

Use the naturalSize and preferredTransform, as appropriate, 
of the asset’s video tracks instead (see also tracksWithMediaType:). 

Więc potrzebujemy AVAssetTrack i chcemy jej naturalSize i preferredTransform. To można uzyskać z następujących czynności:

AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject]; 
CGSize dimensions = CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform); 

atutem jest oczywiście swoją AVAsset.

+1

Hmmm zastosowanie transformacji, jak sugerujesz, daje mi ujemną szerokość :( – Goz

+4

@Goz Wystarczy normalizować komponenty wymiaru za pomocą 'fabsf()'. –

15

Rozdzielczość w Swift:

func resolutionSizeForLocalVideo(url:NSURL) -> CGSize? { 
    guard let track = AVAsset(URL: url).tracksWithMediaType(AVMediaTypeVideo).first else { return nil } 
    let size = CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform) 
    return CGSize(width: fabs(size.width), height: fabs(size.height)) 
} 

Solutions bez preferredTransform nie zwracają poprawne wartości dla niektórych filmów na najnowszych urządzeń!

+0

Witam @Avt może użyć porady dotyczącej eksportu filmów, jeśli nie masz nic przeciwko. Czy możesz pomóc w tych pytaniach? Dziękujemy za poświęcony czas! (1) http://stackoverflow.com/questions/34937862/merge-videos-images-in-avmutablecomposition-using-avmutablecompositiontrack (2) http: // stackoverflow. com/questions/34938904/exported-video-not-at-size-as-source-video – Crashalot

1

Aby wyprowadzić wymiar w AVAsset należy obliczyć Unii wszystkich wizualnych rects torów (po zastosowaniu ich odpowiadający preferowanej transformacji):

CGRect unionRect = CGRectZero; 
for (AVAssetTrack *track in [asset tracksWithMediaCharacteristic:AVMediaCharacteristicVisual]) { 
    CGRect trackRect = CGRectApplyAffineTransform(CGRectMake(0.f, 
                  0.f, 
                  track.naturalSize.width, 
                  track.naturalSize.height), 
                track.preferredTransform); 
    unionRect = CGRectUnion(unionRect, trackRect); 
} 
CGSize naturalSize = unionRect.size; 

metod, które opierają się na CGSizeApplyAffineTransform zawieść, gdy składnik zawiera utwory z niebanalną transformacją afiniczną (np. obrót o 45 stopni) lub jeśli twój zasób zawiera utwory o różnym pochodzeniu (np. dwie ścieżki graniczą obok siebie z pochodzeniem drugiej ścieżki powiększoną o szerokość pierwszego utworu).

Patrz: MediaPlayerPrivateAVFoundationCF::sizeChanged() na https://opensource.apple.com/source/WebCore/WebCore-7536.30.2/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp

+0

Altho David, dla zestawu AVA, który zawiera jedną ścieżkę wideo, odpowiedź @Avt działa poprawnie. Tak? –

+1

@RoiMulia: Myślę, że to niezbyt często dla zasobów, aby mieć jedną ścieżkę wideo z niezerowym przesunięciem, ponieważ prawdopodobnie nie zauważysz błędu podczas używania tego kodu, a także widziałem graczy, którzy ignorują przesunięcie, gdy zasób zawiera tylko jedną ścieżkę. zależy ci na obsłudze w tych skrajnych przypadkach, polecam eksperymentowanie w celu zweryfikowania rzeczywistego zachowania. –

0

Jest to dość proste rozszerzenie dla AVAsset w Swift 4 aby uzyskać rozmiaru pliku wideo, jeżeli są dostępne:

extension AVAsset { 
    var screenSize: CGSize? { 
     if let track = tracks(withMediaType: .video).first { 
      let size = __CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform) 
      return CGSize(width: fabs(size.width), height: fabs(size.height)) 
     } 
     return nil 
    } 
} 
+0

Dzięki - aplikacja została napisana w Objective-C, chociaż (muszę ją jeszcze przepisać). Sprawdzę, czy mogę dostosować twoje rozszerzenie ... – Swissdude